forked from p15670423/monkey
Merge pull request #1728 from guardicore/1605-modify-exploit-result-data
Modify ExploiterResultData
This commit is contained in:
commit
96bd7bca24
|
@ -1,7 +1,6 @@
|
|||
import glob
|
||||
import logging
|
||||
import os
|
||||
import pwd
|
||||
from typing import Dict, Iterable
|
||||
|
||||
from common.utils.attack_utils import ScanStatus
|
||||
|
@ -30,6 +29,8 @@ def get_ssh_info(telemetry_messenger: ITelemetryMessenger) -> Iterable[Dict]:
|
|||
|
||||
|
||||
def _get_home_dirs() -> Iterable[Dict]:
|
||||
import pwd
|
||||
|
||||
root_dir = _get_ssh_struct("root", "")
|
||||
home_dirs = [
|
||||
_get_ssh_struct(x.pw_name, x.pw_dir) for x in pwd.getpwall() if x.pw_dir.startswith("/home")
|
||||
|
|
|
@ -51,7 +51,7 @@ class HostExploiter:
|
|||
def send_exploit_telemetry(self, name: str, result: bool):
|
||||
from infection_monkey.telemetry.exploit_telem import ExploitTelem
|
||||
|
||||
ExploitTelem(
|
||||
ExploitTelem( # stale code
|
||||
name=name,
|
||||
host=self.host,
|
||||
result=result,
|
||||
|
|
|
@ -17,7 +17,8 @@ class UnknownPluginError(Exception):
|
|||
|
||||
|
||||
ExploiterResultData = namedtuple(
|
||||
"ExploiterResultData", ["success", "info", "attempts", "error_message"]
|
||||
"ExploiterResultData",
|
||||
["exploitation_success", "propagation_success", "os", "info", "attempts", "error_message"],
|
||||
)
|
||||
PingScanData = namedtuple("PingScanData", ["response_received", "os"])
|
||||
PortScanData = namedtuple("PortScanData", ["port", "status", "banner", "service"])
|
||||
|
|
|
@ -104,7 +104,7 @@ class Exploiter:
|
|||
)
|
||||
results_callback(exploiter_name, victim_host, exploiter_results)
|
||||
|
||||
if exploiter_name != "ZerologonExploiter" and exploiter_results.success:
|
||||
if exploiter_results.propagation_success:
|
||||
break
|
||||
|
||||
def _run_exploiter(
|
||||
|
|
|
@ -101,20 +101,16 @@ class MockMaster(IMaster):
|
|||
|
||||
def _exploit(self):
|
||||
logger.info("Exploiting victims")
|
||||
result, info, attempts, error_message = self._puppet.exploit_host(
|
||||
"PowerShellExploiter", "10.0.0.1", {}, None
|
||||
)
|
||||
logger.info(f"Attempts for exploiting {attempts}")
|
||||
result = self._puppet.exploit_host("PowerShellExploiter", "10.0.0.1", {}, None)
|
||||
logger.info(f"Attempts for exploiting {result.attempts}")
|
||||
self._telemetry_messenger.send_telemetry(
|
||||
ExploitTelem("PowerShellExploiter", self._hosts["10.0.0.1"], result, info, attempts)
|
||||
ExploitTelem("PowerShellExploiter", self._hosts["10.0.0.1"], result)
|
||||
)
|
||||
|
||||
result, info, attempts, error_message = self._puppet.exploit_host(
|
||||
"SSHExploiter", "10.0.0.3", {}, None
|
||||
)
|
||||
logger.info(f"Attempts for exploiting {attempts}")
|
||||
result = self._puppet.exploit_host("SSHExploiter", "10.0.0.3", {}, None)
|
||||
logger.info(f"Attempts for exploiting {result.attempts}")
|
||||
self._telemetry_messenger.send_telemetry(
|
||||
ExploitTelem("SSHExploiter", self._hosts["10.0.0.3"], result, info, attempts)
|
||||
ExploitTelem("SSHExploiter", self._hosts["10.0.0.3"], result)
|
||||
)
|
||||
logger.info("Finished exploiting victims")
|
||||
|
||||
|
|
|
@ -153,13 +153,16 @@ class Propagator:
|
|||
def _process_exploit_attempts(
|
||||
self, exploiter_name: str, host: VictimHost, result: ExploiterResultData
|
||||
):
|
||||
if result.success:
|
||||
if result.propagation_success:
|
||||
logger.info(f"Successfully propagated to {host} using {exploiter_name}")
|
||||
elif result.exploitation_success:
|
||||
logger.info(
|
||||
f"Successfully exploited (but did not propagate to) {host} using {exploiter_name}"
|
||||
)
|
||||
else:
|
||||
logger.info(
|
||||
f"Failed to propagate to {host} using {exploiter_name}: {result.error_message}"
|
||||
f"Failed to exploit or propagate to {host} using {exploiter_name}: "
|
||||
f"{result.error_message}"
|
||||
)
|
||||
|
||||
self._telemetry_messenger.send_telemetry(
|
||||
ExploitTelem(exploiter_name, host, result.success, result.info, result.attempts)
|
||||
)
|
||||
self._telemetry_messenger.send_telemetry(ExploitTelem(exploiter_name, host, result))
|
||||
|
|
|
@ -177,25 +177,43 @@ class MockPuppet(IPuppet):
|
|||
"vulnerable_ports": [22],
|
||||
"executed_cmds": [],
|
||||
}
|
||||
os_windows = "windows"
|
||||
os_linux = "linux"
|
||||
|
||||
successful_exploiters = {
|
||||
DOT_1: {
|
||||
"PowerShellExploiter": ExploiterResultData(True, info_powershell, attempts, None),
|
||||
"ZerologonExploiter": ExploiterResultData(False, {}, [], "Zerologon failed"),
|
||||
"SSHExploiter": ExploiterResultData(False, info_ssh, attempts, "Failed exploiting"),
|
||||
"PowerShellExploiter": ExploiterResultData(
|
||||
True, True, os_windows, info_powershell, attempts, None
|
||||
),
|
||||
"ZerologonExploiter": ExploiterResultData(
|
||||
False, False, os_windows, {}, [], "Zerologon failed"
|
||||
),
|
||||
"SSHExploiter": ExploiterResultData(
|
||||
False, False, os_linux, info_ssh, attempts, "Failed exploiting"
|
||||
),
|
||||
},
|
||||
DOT_3: {
|
||||
"PowerShellExploiter": ExploiterResultData(
|
||||
False, info_powershell, attempts, "PowerShell Exploiter Failed"
|
||||
False,
|
||||
False,
|
||||
os_windows,
|
||||
info_powershell,
|
||||
attempts,
|
||||
"PowerShell Exploiter Failed",
|
||||
),
|
||||
"SSHExploiter": ExploiterResultData(False, info_ssh, attempts, "Failed exploiting"),
|
||||
"ZerologonExploiter": ExploiterResultData(True, {}, [], None),
|
||||
"SSHExploiter": ExploiterResultData(
|
||||
False, False, os_linux, info_ssh, attempts, "Failed exploiting"
|
||||
),
|
||||
"ZerologonExploiter": ExploiterResultData(True, False, os_windows, {}, [], None),
|
||||
},
|
||||
}
|
||||
|
||||
try:
|
||||
return successful_exploiters[host][name]
|
||||
except KeyError:
|
||||
return ExploiterResultData(False, {}, [], f"{name} failed for host {host}")
|
||||
return ExploiterResultData(
|
||||
False, False, os_linux, {}, [], f"{name} failed for host {host}"
|
||||
)
|
||||
|
||||
def run_payload(self, name: str, options: Dict, interrupt: threading.Event):
|
||||
logger.debug(f"run_payload({name}, {options})")
|
||||
|
|
|
@ -1,33 +1,39 @@
|
|||
from typing import Dict, List
|
||||
from typing import Dict
|
||||
|
||||
from common.common_consts.telem_categories import TelemCategoryEnum
|
||||
from infection_monkey.model.host import VictimHost
|
||||
from infection_monkey.telemetry.base_telem import BaseTelem
|
||||
from monkey.infection_monkey.i_puppet.i_puppet import ExploiterResultData
|
||||
|
||||
|
||||
class ExploitTelem(BaseTelem):
|
||||
def __init__(self, name: str, host: VictimHost, result: bool, info: Dict, attempts: List):
|
||||
def __init__(
|
||||
self,
|
||||
name: str,
|
||||
host: VictimHost,
|
||||
result: ExploiterResultData,
|
||||
):
|
||||
"""
|
||||
Default exploit telemetry constructor
|
||||
:param name: The name of exploiter used
|
||||
:param host: The host machine
|
||||
:param result: The result from the 'exploit_host' method
|
||||
:param info: Information about the exploiter
|
||||
:param attempts: Information about the exploiter's attempts
|
||||
:param result: Data about the exploitation (success status, info, attempts, etc)
|
||||
"""
|
||||
super(ExploitTelem, self).__init__()
|
||||
|
||||
self.name = name
|
||||
self.host = host.__dict__
|
||||
self.result = result
|
||||
self.info = info
|
||||
self.attempts = attempts
|
||||
self.exploitation_result = result.exploitation_success
|
||||
self.propagation_result = result.propagation_success
|
||||
self.info = result.info
|
||||
self.attempts = result.attempts
|
||||
|
||||
telem_category = TelemCategoryEnum.EXPLOIT
|
||||
|
||||
def get_data(self) -> Dict:
|
||||
return {
|
||||
"result": self.result,
|
||||
"exploitation_result": self.exploitation_result,
|
||||
"propagation_result": self.propagation_result,
|
||||
"machine": self.host,
|
||||
"exploiter": self.name,
|
||||
"info": self.info,
|
||||
|
|
|
@ -78,7 +78,7 @@ class EdgeService(Edge):
|
|||
def update_based_on_exploit(self, exploit: Dict):
|
||||
self.exploits.append(exploit)
|
||||
self.save()
|
||||
if exploit["result"]:
|
||||
if exploit["exploitation_success"]:
|
||||
self.set_exploited()
|
||||
|
||||
def set_exploited(self):
|
||||
|
|
|
@ -24,7 +24,7 @@ def process_exploit_telemetry(telemetry_json):
|
|||
|
||||
check_machine_exploited(
|
||||
current_monkey=Monkey.get_single_monkey_by_guid(telemetry_json["monkey_guid"]),
|
||||
exploit_successful=telemetry_json["data"]["result"],
|
||||
exploit_successful=telemetry_json["data"]["exploitation_success"],
|
||||
exploiter=telemetry_json["data"]["exploiter"],
|
||||
target_ip=telemetry_json["data"]["machine"]["ip_addr"],
|
||||
timestamp=telemetry_json["timestamp"],
|
||||
|
@ -65,7 +65,7 @@ def update_network_with_exploit(edge: EdgeService, telemetry_json):
|
|||
new_exploit.pop("machine")
|
||||
new_exploit["timestamp"] = telemetry_json["timestamp"]
|
||||
edge.update_based_on_exploit(new_exploit)
|
||||
if new_exploit["result"]:
|
||||
if new_exploit["exploitation_success"]:
|
||||
NodeService.set_node_exploited(edge.dst_node_id)
|
||||
|
||||
|
||||
|
|
|
@ -100,6 +100,10 @@ dot_3_services = {
|
|||
},
|
||||
}
|
||||
|
||||
os_windows = "windows"
|
||||
|
||||
os_linux = "linux"
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_ip_scanner():
|
||||
|
@ -184,34 +188,38 @@ class MockExploiter:
|
|||
results_callback(
|
||||
"PowerShellExploiter",
|
||||
host,
|
||||
ExploiterResultData(True, {}, {}, None),
|
||||
ExploiterResultData(True, True, os_windows, {}, {}, None),
|
||||
)
|
||||
results_callback(
|
||||
"SSHExploiter",
|
||||
host,
|
||||
ExploiterResultData(False, {}, {}, "SSH FAILED for .1"),
|
||||
ExploiterResultData(False, False, os_linux, {}, {}, "SSH FAILED for .1"),
|
||||
)
|
||||
elif host.ip_addr.endswith(".2"):
|
||||
results_callback(
|
||||
"PowerShellExploiter",
|
||||
host,
|
||||
ExploiterResultData(False, {}, {}, "POWERSHELL FAILED for .2"),
|
||||
ExploiterResultData(
|
||||
False, False, os_windows, {}, {}, "POWERSHELL FAILED for .2"
|
||||
),
|
||||
)
|
||||
results_callback(
|
||||
"SSHExploiter",
|
||||
host,
|
||||
ExploiterResultData(False, {}, {}, "SSH FAILED for .2"),
|
||||
ExploiterResultData(False, False, os_linux, {}, {}, "SSH FAILED for .2"),
|
||||
)
|
||||
elif host.ip_addr.endswith(".3"):
|
||||
results_callback(
|
||||
"PowerShellExploiter",
|
||||
host,
|
||||
ExploiterResultData(False, {}, {}, "POWERSHELL FAILED for .3"),
|
||||
ExploiterResultData(
|
||||
False, False, os_windows, {}, {}, "POWERSHELL FAILED for .3"
|
||||
),
|
||||
)
|
||||
results_callback(
|
||||
"SSHExploiter",
|
||||
host,
|
||||
ExploiterResultData(True, {}, {}, None),
|
||||
ExploiterResultData(True, True, os_linux, {}, {}, None),
|
||||
)
|
||||
|
||||
|
||||
|
@ -246,14 +254,14 @@ def test_exploiter_result_processing(
|
|||
|
||||
if ip.endswith(".1"):
|
||||
if data["exploiter"].startswith("PowerShell"):
|
||||
assert data["result"]
|
||||
assert data["propagation_result"]
|
||||
else:
|
||||
assert not data["result"]
|
||||
assert not data["propagation_result"]
|
||||
elif ip.endswith(".3"):
|
||||
if data["exploiter"].startswith("PowerShell"):
|
||||
assert not data["result"]
|
||||
assert not data["propagation_result"]
|
||||
else:
|
||||
assert data["result"]
|
||||
assert data["propagation_result"]
|
||||
|
||||
|
||||
def test_scan_target_generation(telemetry_messenger_spy, mock_ip_scanner, mock_victim_host_factory):
|
||||
|
|
|
@ -5,6 +5,7 @@ import pytest
|
|||
from infection_monkey.exploit.sshexec import SSHExploiter
|
||||
from infection_monkey.model.host import VictimHost
|
||||
from infection_monkey.telemetry.exploit_telem import ExploitTelem
|
||||
from monkey.infection_monkey.i_puppet.i_puppet import ExploiterResultData
|
||||
|
||||
DOMAIN_NAME = "domain-name"
|
||||
IP = "0.0.0.0"
|
||||
|
@ -30,17 +31,20 @@ EXPLOITER_INFO = {
|
|||
}
|
||||
EXPLOITER_ATTEMPTS = []
|
||||
RESULT = False
|
||||
OS_LINUX = "linux"
|
||||
ERROR_MSG = "failed because yolo"
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def exploit_telem_test_instance():
|
||||
return ExploitTelem(EXPLOITER_NAME, HOST, RESULT, EXPLOITER_INFO, EXPLOITER_ATTEMPTS)
|
||||
return ExploitTelem(EXPLOITER_NAME, HOST, ExploiterResultData(RESULT, RESULT, OS_LINUX, EXPLOITER_INFO, EXPLOITER_ATTEMPTS, ERROR_MSG))
|
||||
|
||||
|
||||
def test_exploit_telem_send(exploit_telem_test_instance, spy_send_telemetry):
|
||||
exploit_telem_test_instance.send()
|
||||
expected_data = {
|
||||
"result": RESULT,
|
||||
"exploitation_result": RESULT,
|
||||
"propagation_result": RESULT,
|
||||
"machine": HOST_AS_DICT,
|
||||
"exploiter": EXPLOITER_NAME,
|
||||
"info": EXPLOITER_INFO,
|
||||
|
|
Loading…
Reference in New Issue