forked from p15670423/monkey
Merge pull request #1825 from guardicore/check-supported-os-for-exploiters
Check supported os for exploiters
This commit is contained in:
commit
6937b1a5c5
|
@ -15,8 +15,6 @@ logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class HostExploiter:
|
class HostExploiter:
|
||||||
_TARGET_OS_TYPE = []
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def _EXPLOITED_SERVICE(self):
|
def _EXPLOITED_SERVICE(self):
|
||||||
|
@ -44,9 +42,6 @@ class HostExploiter:
|
||||||
def set_finish_time(self):
|
def set_finish_time(self):
|
||||||
self.exploit_info["finished"] = datetime.now().isoformat()
|
self.exploit_info["finished"] = datetime.now().isoformat()
|
||||||
|
|
||||||
def is_os_supported(self):
|
|
||||||
return self.host.os.get("type") in self._TARGET_OS_TYPE
|
|
||||||
|
|
||||||
def report_login_attempt(self, result, user, password="", lm_hash="", ntlm_hash="", ssh_key=""):
|
def report_login_attempt(self, result, user, password="", lm_hash="", ntlm_hash="", ssh_key=""):
|
||||||
self.exploit_attempts.append(
|
self.exploit_attempts.append(
|
||||||
{
|
{
|
||||||
|
|
|
@ -19,7 +19,6 @@ logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class DrupalExploiter(WebRCE):
|
class DrupalExploiter(WebRCE):
|
||||||
_TARGET_OS_TYPE = ["linux", "windows"]
|
|
||||||
_EXPLOITED_SERVICE = "Drupal Server"
|
_EXPLOITED_SERVICE = "Drupal Server"
|
||||||
|
|
||||||
def __init__(self, host):
|
def __init__(self, host):
|
||||||
|
|
|
@ -25,7 +25,6 @@ from infection_monkey.utils.commands import build_monkey_commandline
|
||||||
|
|
||||||
|
|
||||||
class HadoopExploiter(WebRCE):
|
class HadoopExploiter(WebRCE):
|
||||||
_TARGET_OS_TYPE = ["linux", "windows"]
|
|
||||||
_EXPLOITED_SERVICE = "Hadoop"
|
_EXPLOITED_SERVICE = "Hadoop"
|
||||||
HADOOP_PORTS = [("8088", False)]
|
HADOOP_PORTS = [("8088", False)]
|
||||||
# How long we have our http server open for downloads in seconds
|
# How long we have our http server open for downloads in seconds
|
||||||
|
|
|
@ -27,7 +27,6 @@ logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class Log4ShellExploiter(WebRCE):
|
class Log4ShellExploiter(WebRCE):
|
||||||
_TARGET_OS_TYPE = ["linux", "windows"]
|
|
||||||
_EXPLOITED_SERVICE = "Log4j"
|
_EXPLOITED_SERVICE = "Log4j"
|
||||||
SERVER_SHUTDOWN_TIMEOUT = LONG_REQUEST_TIMEOUT
|
SERVER_SHUTDOWN_TIMEOUT = LONG_REQUEST_TIMEOUT
|
||||||
REQUEST_TO_VICTIM_TIMEOUT = MEDIUM_REQUEST_TIMEOUT
|
REQUEST_TO_VICTIM_TIMEOUT = MEDIUM_REQUEST_TIMEOUT
|
||||||
|
|
|
@ -23,7 +23,6 @@ logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
class MSSQLExploiter(HostExploiter):
|
class MSSQLExploiter(HostExploiter):
|
||||||
_EXPLOITED_SERVICE = "MSSQL"
|
_EXPLOITED_SERVICE = "MSSQL"
|
||||||
_TARGET_OS_TYPE = ["windows"]
|
|
||||||
LOGIN_TIMEOUT = LONG_REQUEST_TIMEOUT
|
LOGIN_TIMEOUT = LONG_REQUEST_TIMEOUT
|
||||||
QUERY_TIMEOUT = LONG_REQUEST_TIMEOUT
|
QUERY_TIMEOUT = LONG_REQUEST_TIMEOUT
|
||||||
# Time in seconds to wait between MSSQL queries.
|
# Time in seconds to wait between MSSQL queries.
|
||||||
|
|
|
@ -31,7 +31,6 @@ class RemoteAgentExecutionError(Exception):
|
||||||
|
|
||||||
|
|
||||||
class PowerShellExploiter(HostExploiter):
|
class PowerShellExploiter(HostExploiter):
|
||||||
_TARGET_OS_TYPE = ["windows"]
|
|
||||||
_EXPLOITED_SERVICE = "PowerShell Remoting (WinRM)"
|
_EXPLOITED_SERVICE = "PowerShell Remoting (WinRM)"
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
|
@ -21,7 +21,6 @@ logger = getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class SMBExploiter(HostExploiter):
|
class SMBExploiter(HostExploiter):
|
||||||
_TARGET_OS_TYPE = ["windows"]
|
|
||||||
_EXPLOITED_SERVICE = "SMB"
|
_EXPLOITED_SERVICE = "SMB"
|
||||||
KNOWN_PROTOCOLS = {
|
KNOWN_PROTOCOLS = {
|
||||||
"139/SMB": (r"ncacn_np:%s[\pipe\svcctl]", 139),
|
"139/SMB": (r"ncacn_np:%s[\pipe\svcctl]", 139),
|
||||||
|
|
|
@ -31,7 +31,6 @@ TRANSFER_UPDATE_RATE = 15
|
||||||
|
|
||||||
|
|
||||||
class SSHExploiter(HostExploiter):
|
class SSHExploiter(HostExploiter):
|
||||||
_TARGET_OS_TYPE = ["linux", None]
|
|
||||||
_EXPLOITED_SERVICE = "SSH"
|
_EXPLOITED_SERVICE = "SSH"
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
|
@ -20,7 +20,6 @@ DOWNLOAD_TIMEOUT = 300
|
||||||
|
|
||||||
|
|
||||||
class Struts2Exploiter(WebRCE):
|
class Struts2Exploiter(WebRCE):
|
||||||
_TARGET_OS_TYPE = ["linux", "windows"]
|
|
||||||
_EXPLOITED_SERVICE = "Struts2"
|
_EXPLOITED_SERVICE = "Struts2"
|
||||||
|
|
||||||
def __init__(self, host):
|
def __init__(self, host):
|
||||||
|
|
|
@ -29,7 +29,6 @@ HEADERS = {
|
||||||
|
|
||||||
|
|
||||||
class WebLogicExploiter(HostExploiter):
|
class WebLogicExploiter(HostExploiter):
|
||||||
_TARGET_OS_TYPE = ["linux", "windows"]
|
|
||||||
_EXPLOITED_SERVICE = "Weblogic"
|
_EXPLOITED_SERVICE = "Weblogic"
|
||||||
|
|
||||||
def _exploit_host(self):
|
def _exploit_host(self):
|
||||||
|
@ -58,7 +57,6 @@ class WebLogic201710271(WebRCE):
|
||||||
"/wls-wsat/RegistrationRequesterPortType11",
|
"/wls-wsat/RegistrationRequesterPortType11",
|
||||||
]
|
]
|
||||||
|
|
||||||
_TARGET_OS_TYPE = WebLogicExploiter._TARGET_OS_TYPE
|
|
||||||
_EXPLOITED_SERVICE = WebLogicExploiter._EXPLOITED_SERVICE
|
_EXPLOITED_SERVICE = WebLogicExploiter._EXPLOITED_SERVICE
|
||||||
|
|
||||||
def __init__(self, host):
|
def __init__(self, host):
|
||||||
|
@ -257,7 +255,6 @@ class WebLogic20192725(WebRCE):
|
||||||
URLS = ["_async/AsyncResponseServiceHttps"]
|
URLS = ["_async/AsyncResponseServiceHttps"]
|
||||||
DELAY_BEFORE_EXPLOITING_SECONDS = 5
|
DELAY_BEFORE_EXPLOITING_SECONDS = 5
|
||||||
|
|
||||||
_TARGET_OS_TYPE = WebLogicExploiter._TARGET_OS_TYPE
|
|
||||||
_EXPLOITED_SERVICE = WebLogicExploiter._EXPLOITED_SERVICE
|
_EXPLOITED_SERVICE = WebLogicExploiter._EXPLOITED_SERVICE
|
||||||
|
|
||||||
def __init__(self, host):
|
def __init__(self, host):
|
||||||
|
|
|
@ -22,7 +22,6 @@ logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class WmiExploiter(HostExploiter):
|
class WmiExploiter(HostExploiter):
|
||||||
_TARGET_OS_TYPE = ["windows"]
|
|
||||||
_EXPLOITED_SERVICE = "WMI (Windows Management Instrumentation)"
|
_EXPLOITED_SERVICE = "WMI (Windows Management Instrumentation)"
|
||||||
|
|
||||||
@WmiTools.impacket_user
|
@WmiTools.impacket_user
|
||||||
|
|
|
@ -33,7 +33,6 @@ logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class ZerologonExploiter(HostExploiter):
|
class ZerologonExploiter(HostExploiter):
|
||||||
_TARGET_OS_TYPE = ["windows"]
|
|
||||||
_EXPLOITED_SERVICE = "Netlogon"
|
_EXPLOITED_SERVICE = "Netlogon"
|
||||||
MAX_ATTEMPTS = 2000 # For 2000, expected average number of attempts needed: 256.
|
MAX_ATTEMPTS = 2000 # For 2000, expected average number of attempts needed: 256.
|
||||||
ERROR_CODE_ACCESS_DENIED = 0xC0000022
|
ERROR_CODE_ACCESS_DENIED = 0xC0000022
|
||||||
|
|
|
@ -114,6 +114,16 @@ class Exploiter:
|
||||||
|
|
||||||
for exploiter in interruptible_iter(exploiters_to_run, stop):
|
for exploiter in interruptible_iter(exploiters_to_run, stop):
|
||||||
exploiter_name = exploiter["name"]
|
exploiter_name = exploiter["name"]
|
||||||
|
victim_os = victim_host.os.get("type")
|
||||||
|
|
||||||
|
# We want to try all exploiters if the victim's OS is unknown
|
||||||
|
if victim_os is not None and victim_os not in exploiter["supported_os"]:
|
||||||
|
logger.debug(
|
||||||
|
f"Skipping {exploiter_name} because it does not support "
|
||||||
|
f"the victim's OS ({victim_os})"
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
|
||||||
exploiter_results = self._run_exploiter(
|
exploiter_results = self._run_exploiter(
|
||||||
exploiter_name, exploiter["options"], victim_host, current_depth, stop
|
exploiter_name, exploiter["options"], victim_host, current_depth, stop
|
||||||
)
|
)
|
||||||
|
|
|
@ -163,8 +163,8 @@ class MockPuppet(IPuppet):
|
||||||
"ssh_key": host,
|
"ssh_key": host,
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
info_powershell = {
|
info_wmi = {
|
||||||
"display_name": "PowerShell",
|
"display_name": "WMI",
|
||||||
"started": "2021-11-25T15:57:06.307696",
|
"started": "2021-11-25T15:57:06.307696",
|
||||||
"finished": "2021-11-25T15:58:33.788238",
|
"finished": "2021-11-25T15:58:33.788238",
|
||||||
"vulnerable_urls": [],
|
"vulnerable_urls": [],
|
||||||
|
@ -189,15 +189,15 @@ class MockPuppet(IPuppet):
|
||||||
|
|
||||||
successful_exploiters = {
|
successful_exploiters = {
|
||||||
DOT_1: {
|
DOT_1: {
|
||||||
"PowerShellExploiter": ExploiterResultData(
|
|
||||||
True, True, False, os_windows, info_powershell, attempts, None
|
|
||||||
),
|
|
||||||
"ZerologonExploiter": ExploiterResultData(
|
"ZerologonExploiter": ExploiterResultData(
|
||||||
False, False, False, os_windows, {}, [], "Zerologon failed"
|
False, False, False, os_windows, {}, [], "Zerologon failed"
|
||||||
),
|
),
|
||||||
"SSHExploiter": ExploiterResultData(
|
"SSHExploiter": ExploiterResultData(
|
||||||
False, False, False, os_linux, info_ssh, attempts, "Failed exploiting"
|
False, False, False, os_linux, info_ssh, attempts, "Failed exploiting"
|
||||||
),
|
),
|
||||||
|
"WmiExploiter": ExploiterResultData(
|
||||||
|
True, True, False, os_windows, info_wmi, attempts, None
|
||||||
|
),
|
||||||
},
|
},
|
||||||
DOT_3: {
|
DOT_3: {
|
||||||
"PowerShellExploiter": ExploiterResultData(
|
"PowerShellExploiter": ExploiterResultData(
|
||||||
|
@ -205,7 +205,7 @@ class MockPuppet(IPuppet):
|
||||||
False,
|
False,
|
||||||
False,
|
False,
|
||||||
os_windows,
|
os_windows,
|
||||||
info_powershell,
|
info_wmi,
|
||||||
attempts,
|
attempts,
|
||||||
"PowerShell Exploiter Failed",
|
"PowerShell Exploiter Failed",
|
||||||
),
|
),
|
||||||
|
|
|
@ -3,6 +3,7 @@ import copy
|
||||||
import functools
|
import functools
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
|
from itertools import chain
|
||||||
from typing import Any, Dict, List
|
from typing import Any, Dict, List
|
||||||
|
|
||||||
from jsonschema import Draft4Validator, validators
|
from jsonschema import Draft4Validator, validators
|
||||||
|
@ -629,9 +630,10 @@ class ConfigService:
|
||||||
|
|
||||||
config.pop(flat_config_exploiter_classes_field, None)
|
config.pop(flat_config_exploiter_classes_field, None)
|
||||||
|
|
||||||
return ConfigService._add_smb_download_timeout_to_exploiters(
|
formatted_exploiters_config = ConfigService._add_smb_download_timeout_to_exploiters(
|
||||||
config, formatted_exploiters_config
|
config, formatted_exploiters_config
|
||||||
)
|
)
|
||||||
|
return ConfigService._add_supported_os_to_exploiters(formatted_exploiters_config)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _add_smb_download_timeout_to_exploiters(
|
def _add_smb_download_timeout_to_exploiters(
|
||||||
|
@ -644,3 +646,23 @@ class ConfigService:
|
||||||
exploiter["options"]["smb_download_timeout"] = flat_config["smb_download_timeout"]
|
exploiter["options"]["smb_download_timeout"] = flat_config["smb_download_timeout"]
|
||||||
|
|
||||||
return new_config
|
return new_config
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _add_supported_os_to_exploiters(
|
||||||
|
formatted_config: Dict,
|
||||||
|
) -> Dict[str, List[Dict[str, Any]]]:
|
||||||
|
supported_os = {
|
||||||
|
"HadoopExploiter": ["linux", "windows"],
|
||||||
|
"Log4ShellExploiter": ["linux", "windows"],
|
||||||
|
"MSSQLExploiter": ["windows"],
|
||||||
|
"PowerShellExploiter": ["windows"],
|
||||||
|
"SSHExploiter": ["linux"],
|
||||||
|
"SmbExploiter": ["windows"],
|
||||||
|
"WmiExploiter": ["windows"],
|
||||||
|
"ZerologonExploiter": ["windows"],
|
||||||
|
}
|
||||||
|
new_config = copy.deepcopy(formatted_config)
|
||||||
|
for exploiter in chain(new_config["brute_force"], new_config["vulnerability"]):
|
||||||
|
exploiter["supported_os"] = supported_os.get(exploiter["name"], [])
|
||||||
|
|
||||||
|
return new_config
|
||||||
|
|
|
@ -45,20 +45,21 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"exploiters": {
|
"exploiters": {
|
||||||
|
"options": {},
|
||||||
"brute_force": [
|
"brute_force": [
|
||||||
{"name": "MSSQLExploiter"},
|
{"name": "MSSQLExploiter", "supported_os": ["windows"], "options": {}},
|
||||||
{"name": "PowerShellExploiter"},
|
{"name": "PowerShellExploiter", "supported_os": ["windows"], "options": {}},
|
||||||
{"name": "SmbExploiter"},
|
{"name": "SmbExploiter", "supported_os": ["windows"], "options": {}},
|
||||||
{"name": "SSHExploiter"},
|
{"name": "SSHExploiter", "supported_os": ["linux"], "options": {}},
|
||||||
{"name": "WmiExploiter"}
|
{"name": "WmiExploiter", "supported_os": ["windows"], "options": {}}
|
||||||
],
|
],
|
||||||
"vulnerability": [
|
"vulnerability": [
|
||||||
{"name": "DrupalExploiter"},
|
{"name": "DrupalExploiter", "supported_os": ["linux", "windows"], "options": {}},
|
||||||
{"name": "HadoopExploiter"},
|
{"name": "HadoopExploiter", "supported_os": ["linux", "windows"], "options": {}},
|
||||||
{"name": "ShellShockExploiter"},
|
{"name": "ShellShockExploiter", "supported_os": ["linux"], "options": {}},
|
||||||
{"name": "Struts2Exploiter"},
|
{"name": "Struts2Exploiter", "supported_os": ["linux", "windows"], "options": {}},
|
||||||
{"name": "WebLogicExploiter"},
|
{"name": "WebLogicExploiter", "supported_os": ["linux", "windows"], "options": {}},
|
||||||
{"name": "ZerologonExploiter"}
|
{"name": "ZerologonExploiter", "supported_os": ["windows"], "options": {}}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -102,7 +103,7 @@
|
||||||
"other_behaviors": {"readme": true}
|
"other_behaviors": {"readme": true}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"system_info_collector_classes": [
|
"credential_collector_classes": [
|
||||||
"MimikatzCollector",
|
"MimikatzCollector",
|
||||||
"SSHCollector"
|
"SSHCollector"
|
||||||
]
|
]
|
||||||
|
|
|
@ -55,7 +55,8 @@
|
||||||
"HadoopExploiter",
|
"HadoopExploiter",
|
||||||
"MSSQLExploiter",
|
"MSSQLExploiter",
|
||||||
"DrupalExploiter",
|
"DrupalExploiter",
|
||||||
"PowerShellExploiter"
|
"PowerShellExploiter",
|
||||||
|
"Log4ShellExploiter"
|
||||||
],
|
],
|
||||||
"export_monkey_telems": false,
|
"export_monkey_telems": false,
|
||||||
"finger_classes": [
|
"finger_classes": [
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import logging
|
import logging
|
||||||
from queue import Queue
|
from queue import Queue
|
||||||
from threading import Barrier, Event
|
from threading import Barrier, Event
|
||||||
|
from typing import Iterable
|
||||||
from unittest.mock import MagicMock
|
from unittest.mock import MagicMock
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
@ -37,29 +38,47 @@ def exploiter_config():
|
||||||
return {
|
return {
|
||||||
"options": {"dropper_path_linux": "/tmp/monkey"},
|
"options": {"dropper_path_linux": "/tmp/monkey"},
|
||||||
"brute_force": [
|
"brute_force": [
|
||||||
{"name": "PowerShellExploiter", "options": {"timeout": 10}},
|
{"name": "HadoopExploiter", "supported_os": ["windows"], "options": {"timeout": 10}},
|
||||||
{"name": "SSHExploiter", "options": {}},
|
{"name": "SSHExploiter", "supported_os": ["linux"], "options": {}},
|
||||||
|
{"name": "WmiExploiter", "supported_os": ["windows"], "options": {"timeout": 10}},
|
||||||
],
|
],
|
||||||
"vulnerability": [
|
"vulnerability": [
|
||||||
{"name": "ZerologonExploiter", "options": {}},
|
{"name": "ZerologonExploiter", "supported_os": ["windows"], "options": {}},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def hosts():
|
def hosts():
|
||||||
return [VictimHost("10.0.0.1"), VictimHost("10.0.0.3")]
|
host_1 = VictimHost("10.0.0.1")
|
||||||
|
host_2 = VictimHost("10.0.0.3")
|
||||||
|
return [host_1, host_2]
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def hosts_to_exploit(hosts):
|
def hosts_to_exploit(hosts):
|
||||||
|
return enqueue_hosts(hosts)
|
||||||
|
|
||||||
|
|
||||||
|
def enqueue_hosts(hosts: Iterable[VictimHost]):
|
||||||
q = Queue()
|
q = Queue()
|
||||||
q.put(hosts[0])
|
for h in hosts:
|
||||||
q.put(hosts[1])
|
q.put(h)
|
||||||
|
|
||||||
return q
|
return q
|
||||||
|
|
||||||
|
|
||||||
|
def get_host_exploit_combos_from_call_args_list(call_args_list):
|
||||||
|
host_exploit_combos = set()
|
||||||
|
|
||||||
|
for call_args in call_args_list:
|
||||||
|
victim_host = call_args[0][0]
|
||||||
|
exploiter_name = call_args[0][1]
|
||||||
|
host_exploit_combos.add((victim_host, exploiter_name))
|
||||||
|
|
||||||
|
return host_exploit_combos
|
||||||
|
|
||||||
|
|
||||||
CREDENTIALS_FOR_PROPAGATION = {"usernames": ["m0nk3y", "user"], "passwords": ["1234", "pword"]}
|
CREDENTIALS_FOR_PROPAGATION = {"usernames": ["m0nk3y", "user"], "passwords": ["1234", "pword"]}
|
||||||
|
|
||||||
|
|
||||||
|
@ -69,12 +88,12 @@ def get_credentials_for_propagation():
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def run_exploiters(exploiter_config, hosts_to_exploit, callback, scan_completed, stop):
|
def run_exploiters(exploiter_config, hosts_to_exploit, callback, scan_completed, stop):
|
||||||
def inner(puppet, num_workers):
|
def inner(puppet, num_workers, hosts=hosts_to_exploit):
|
||||||
# Set this so that Exploiter() exits once it has processed all victims
|
# Set this so that Exploiter() exits once it has processed all victims
|
||||||
scan_completed.set()
|
scan_completed.set()
|
||||||
|
|
||||||
e = Exploiter(puppet, num_workers, get_credentials_for_propagation)
|
e = Exploiter(puppet, num_workers, get_credentials_for_propagation)
|
||||||
e.exploit_hosts(exploiter_config, hosts_to_exploit, 1, callback, scan_completed, stop)
|
e.exploit_hosts(exploiter_config, hosts, 1, callback, scan_completed, stop)
|
||||||
|
|
||||||
return inner
|
return inner
|
||||||
|
|
||||||
|
@ -82,18 +101,16 @@ def run_exploiters(exploiter_config, hosts_to_exploit, callback, scan_completed,
|
||||||
def test_exploiter(callback, hosts, hosts_to_exploit, run_exploiters):
|
def test_exploiter(callback, hosts, hosts_to_exploit, run_exploiters):
|
||||||
run_exploiters(MockPuppet(), 2)
|
run_exploiters(MockPuppet(), 2)
|
||||||
|
|
||||||
assert callback.call_count == 5
|
assert callback.call_count == 8
|
||||||
host_exploit_combos = set()
|
host_exploit_combos = get_host_exploit_combos_from_call_args_list(callback.call_args_list)
|
||||||
|
|
||||||
for i in range(0, 5):
|
|
||||||
victim_host = callback.call_args_list[i][0][0]
|
|
||||||
exploiter_name = callback.call_args_list[i][0][1]
|
|
||||||
host_exploit_combos.add((victim_host, exploiter_name))
|
|
||||||
|
|
||||||
assert ("ZerologonExploiter", hosts[0]) in host_exploit_combos
|
assert ("ZerologonExploiter", hosts[0]) in host_exploit_combos
|
||||||
assert ("PowerShellExploiter", hosts[0]) in host_exploit_combos
|
assert ("HadoopExploiter", hosts[0]) in host_exploit_combos
|
||||||
|
assert ("SSHExploiter", hosts[0]) in host_exploit_combos
|
||||||
|
assert ("WmiExploiter", hosts[0]) in host_exploit_combos
|
||||||
assert ("ZerologonExploiter", hosts[1]) in host_exploit_combos
|
assert ("ZerologonExploiter", hosts[1]) in host_exploit_combos
|
||||||
assert ("PowerShellExploiter", hosts[1]) in host_exploit_combos
|
assert ("HadoopExploiter", hosts[1]) in host_exploit_combos
|
||||||
|
assert ("WmiExploiter", hosts[1]) in host_exploit_combos
|
||||||
assert ("SSHExploiter", hosts[1]) in host_exploit_combos
|
assert ("SSHExploiter", hosts[1]) in host_exploit_combos
|
||||||
|
|
||||||
|
|
||||||
|
@ -132,10 +149,53 @@ def test_exploiter_raises_exception(callback, hosts, hosts_to_exploit, run_explo
|
||||||
mock_puppet.exploit_host = MagicMock(side_effect=Exception(error_message))
|
mock_puppet.exploit_host = MagicMock(side_effect=Exception(error_message))
|
||||||
run_exploiters(mock_puppet, 3)
|
run_exploiters(mock_puppet, 3)
|
||||||
|
|
||||||
assert callback.call_count == 6
|
assert callback.call_count == 8
|
||||||
|
|
||||||
for i in range(0, 6):
|
for i in range(0, 6):
|
||||||
exploit_result_data = callback.call_args_list[i][0][2]
|
exploit_result_data = callback.call_args_list[i][0][2]
|
||||||
assert exploit_result_data.exploitation_success is False
|
assert exploit_result_data.exploitation_success is False
|
||||||
assert exploit_result_data.propagation_success is False
|
assert exploit_result_data.propagation_success is False
|
||||||
assert error_message in exploit_result_data.error_message
|
assert error_message in exploit_result_data.error_message
|
||||||
|
|
||||||
|
|
||||||
|
def test_windows_exploiters_run_on_windows_host(callback, hosts, hosts_to_exploit, run_exploiters):
|
||||||
|
host = VictimHost("10.0.0.1")
|
||||||
|
host.os["type"] = "windows"
|
||||||
|
q = enqueue_hosts([host])
|
||||||
|
run_exploiters(MockPuppet(), 1, q)
|
||||||
|
|
||||||
|
assert callback.call_count == 3
|
||||||
|
host_exploit_combos = get_host_exploit_combos_from_call_args_list(callback.call_args_list)
|
||||||
|
|
||||||
|
assert ("SSHExploiter", host) not in host_exploit_combos
|
||||||
|
|
||||||
|
|
||||||
|
def test_linux_exploiters_run_on_linux_host(callback, hosts, hosts_to_exploit, run_exploiters):
|
||||||
|
host = VictimHost("10.0.0.1")
|
||||||
|
host.os["type"] = "linux"
|
||||||
|
q = enqueue_hosts([host])
|
||||||
|
run_exploiters(MockPuppet(), 1, q)
|
||||||
|
|
||||||
|
assert callback.call_count == 1
|
||||||
|
host_exploit_combos = get_host_exploit_combos_from_call_args_list(callback.call_args_list)
|
||||||
|
|
||||||
|
assert ("SSHExploiter", host) in host_exploit_combos
|
||||||
|
|
||||||
|
|
||||||
|
def test_all_exploiters_run_on_unknown_host(callback, hosts, hosts_to_exploit, run_exploiters):
|
||||||
|
host = VictimHost("10.0.0.1")
|
||||||
|
try:
|
||||||
|
del host.os["type"]
|
||||||
|
except KeyError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
q = enqueue_hosts([host])
|
||||||
|
run_exploiters(MockPuppet(), 1, q)
|
||||||
|
|
||||||
|
assert callback.call_count == 4
|
||||||
|
host_exploit_combos = get_host_exploit_combos_from_call_args_list(callback.call_args_list)
|
||||||
|
|
||||||
|
assert ("ZerologonExploiter", hosts[0]) in host_exploit_combos
|
||||||
|
assert ("HadoopExploiter", hosts[0]) in host_exploit_combos
|
||||||
|
assert ("SSHExploiter", host) in host_exploit_combos
|
||||||
|
assert ("WmiExploiter", hosts[0]) in host_exploit_combos
|
||||||
|
|
|
@ -177,18 +177,27 @@ def test_format_config_for_agent__exploiters(flat_monkey_config):
|
||||||
"http_ports": [80, 443, 7001, 8008, 8080, 9200],
|
"http_ports": [80, 443, 7001, 8008, 8080, 9200],
|
||||||
},
|
},
|
||||||
"brute_force": [
|
"brute_force": [
|
||||||
{"name": "MSSQLExploiter", "options": {}},
|
{"name": "MSSQLExploiter", "supported_os": ["windows"], "options": {}},
|
||||||
{"name": "PowerShellExploiter", "options": {}},
|
{"name": "PowerShellExploiter", "supported_os": ["windows"], "options": {}},
|
||||||
{"name": "SSHExploiter", "options": {}},
|
{"name": "SSHExploiter", "supported_os": ["linux"], "options": {}},
|
||||||
{"name": "SmbExploiter", "options": {"smb_download_timeout": 300}},
|
{
|
||||||
{"name": "WmiExploiter", "options": {"smb_download_timeout": 300}},
|
"name": "SmbExploiter",
|
||||||
|
"supported_os": ["windows"],
|
||||||
|
"options": {"smb_download_timeout": 300},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "WmiExploiter",
|
||||||
|
"supported_os": ["windows"],
|
||||||
|
"options": {"smb_download_timeout": 300},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
"vulnerability": [
|
"vulnerability": [
|
||||||
{"name": "DrupalExploiter", "options": {}},
|
{"name": "DrupalExploiter", "supported_os": [], "options": {}},
|
||||||
{"name": "HadoopExploiter", "options": {}},
|
{"name": "HadoopExploiter", "supported_os": ["linux", "windows"], "options": {}},
|
||||||
{"name": "Struts2Exploiter", "options": {}},
|
{"name": "Log4ShellExploiter", "supported_os": ["linux", "windows"], "options": {}},
|
||||||
{"name": "WebLogicExploiter", "options": {}},
|
{"name": "Struts2Exploiter", "supported_os": [], "options": {}},
|
||||||
{"name": "ZerologonExploiter", "options": {}},
|
{"name": "WebLogicExploiter", "supported_os": [], "options": {}},
|
||||||
|
{"name": "ZerologonExploiter", "supported_os": ["windows"], "options": {}},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
ConfigService.format_flat_config_for_agent(flat_monkey_config)
|
ConfigService.format_flat_config_for_agent(flat_monkey_config)
|
||||||
|
|
Loading…
Reference in New Issue