diff --git a/monkey/infection_monkey/exploit/HostExploiter.py b/monkey/infection_monkey/exploit/HostExploiter.py index 4b0c78c21..8ca63c3ba 100644 --- a/monkey/infection_monkey/exploit/HostExploiter.py +++ b/monkey/infection_monkey/exploit/HostExploiter.py @@ -9,7 +9,7 @@ from common.utils.exceptions import FailedExploitationError from infection_monkey.i_puppet import ExploiterResultData from infection_monkey.telemetry.messengers.i_telemetry_messenger import ITelemetryMessenger -from . import IAgentRepository +from . import IAgentBinaryRepository logger = logging.getLogger(__name__) @@ -61,7 +61,7 @@ class HostExploiter: current_depth: int, telemetry_messenger: ITelemetryMessenger, event_queue: IEventQueue, - agent_repository: IAgentRepository, + agent_binary_repository: IAgentBinaryRepository, options: Dict, interrupt: threading.Event, ): @@ -69,7 +69,7 @@ class HostExploiter: self.current_depth = current_depth self.telemetry_messenger = telemetry_messenger self.event_queue = event_queue - self.agent_repository = agent_repository + self.agent_binary_repository = agent_binary_repository self.options = options self.interrupt = interrupt diff --git a/monkey/infection_monkey/exploit/__init__.py b/monkey/infection_monkey/exploit/__init__.py index 7e5733502..195e880ad 100644 --- a/monkey/infection_monkey/exploit/__init__.py +++ b/monkey/infection_monkey/exploit/__init__.py @@ -1,3 +1,3 @@ -from .i_agent_repository import IAgentRepository -from .caching_agent_repository import CachingAgentRepository +from .i_agent_binary_repository import IAgentBinaryRepository +from .caching_agent_binary_repository import CachingAgentBinaryRepository from .exploiter_wrapper import ExploiterWrapper diff --git a/monkey/infection_monkey/exploit/caching_agent_repository.py b/monkey/infection_monkey/exploit/caching_agent_binary_repository.py similarity index 79% rename from monkey/infection_monkey/exploit/caching_agent_repository.py rename to monkey/infection_monkey/exploit/caching_agent_binary_repository.py index 028a5f869..f3d4dc73a 100644 --- a/monkey/infection_monkey/exploit/caching_agent_repository.py +++ b/monkey/infection_monkey/exploit/caching_agent_binary_repository.py @@ -8,14 +8,14 @@ import requests from common import OperatingSystem from common.common_consts.timeouts import MEDIUM_REQUEST_TIMEOUT -from . import IAgentRepository +from . import IAgentBinaryRepository -class CachingAgentRepository(IAgentRepository): +class CachingAgentBinaryRepository(IAgentBinaryRepository): """ - CachingAgentRepository implements the IAgentRepository interface and downloads the requested - agent binary from the island on request. The agent binary is cached so that only one request is - actually sent to the island for each requested binary. + CachingAgentBinaryRepository implements the IAgentBinaryRepository interface and downloads the + requested agent binary from the island on request. The agent binary is cached so that only one + request is actually sent to the island for each requested binary. """ def __init__(self, island_url: str, proxies: Mapping[str, str]): diff --git a/monkey/infection_monkey/exploit/exploiter_wrapper.py b/monkey/infection_monkey/exploit/exploiter_wrapper.py index 8e9d4f22f..3e369134f 100644 --- a/monkey/infection_monkey/exploit/exploiter_wrapper.py +++ b/monkey/infection_monkey/exploit/exploiter_wrapper.py @@ -5,7 +5,7 @@ from common.event_queue import IEventQueue from infection_monkey.model import VictimHost from infection_monkey.telemetry.messengers.i_telemetry_messenger import ITelemetryMessenger -from . import IAgentRepository +from . import IAgentBinaryRepository from .HostExploiter import HostExploiter @@ -23,12 +23,12 @@ class ExploiterWrapper: exploit_class: Type[HostExploiter], telemetry_messenger: ITelemetryMessenger, event_queue: IEventQueue, - agent_repository: IAgentRepository, + agent_binary_repository: IAgentBinaryRepository, ): self._exploit_class = exploit_class self._telemetry_messenger = telemetry_messenger self._event_queue = event_queue - self._agent_repository = agent_repository + self._agent_binary_repository = agent_binary_repository def exploit_host( self, host: VictimHost, current_depth: int, options: Dict, interrupt: threading.Event @@ -39,7 +39,7 @@ class ExploiterWrapper: current_depth, self._telemetry_messenger, self._event_queue, - self._agent_repository, + self._agent_binary_repository, options, interrupt, ) @@ -48,13 +48,16 @@ class ExploiterWrapper: self, telemetry_messenger: ITelemetryMessenger, event_queue: IEventQueue, - agent_repository: IAgentRepository, + agent_binary_repository: IAgentBinaryRepository, ): self._telemetry_messenger = telemetry_messenger self._event_queue = event_queue - self._agent_repository = agent_repository + self._agent_binary_repository = agent_binary_repository def wrap(self, exploit_class: Type[HostExploiter]): return ExploiterWrapper.Inner( - exploit_class, self._telemetry_messenger, self._event_queue, self._agent_repository + exploit_class, + self._telemetry_messenger, + self._event_queue, + self._agent_binary_repository, ) diff --git a/monkey/infection_monkey/exploit/hadoop.py b/monkey/infection_monkey/exploit/hadoop.py index 5cf30f23c..2c0ceaa73 100644 --- a/monkey/infection_monkey/exploit/hadoop.py +++ b/monkey/infection_monkey/exploit/hadoop.py @@ -48,7 +48,7 @@ class HadoopExploiter(WebRCE): return self.exploit_result http_path, http_thread = HTTPTools.create_locked_transfer( - self.host, str(monkey_path_on_victim), self.agent_repository + self.host, str(monkey_path_on_victim), self.agent_binary_repository ) try: diff --git a/monkey/infection_monkey/exploit/i_agent_repository.py b/monkey/infection_monkey/exploit/i_agent_binary_repository.py similarity index 51% rename from monkey/infection_monkey/exploit/i_agent_repository.py rename to monkey/infection_monkey/exploit/i_agent_binary_repository.py index cf5141201..09de7a696 100644 --- a/monkey/infection_monkey/exploit/i_agent_repository.py +++ b/monkey/infection_monkey/exploit/i_agent_binary_repository.py @@ -3,15 +3,15 @@ import io from common import OperatingSystem -# TODO: The Island also has an IAgentRepository with a totally different interface. At the moment, -# the Island and Agent have different needs, but at some point we should unify these. +# TODO: The Island also has an IAgentBinaryRepository with a totally different interface. At the +# moment, the Island and Agent have different needs, but at some point we should unify these. -class IAgentRepository(metaclass=abc.ABCMeta): +class IAgentBinaryRepository(metaclass=abc.ABCMeta): """ - IAgentRepository provides an interface for other components to access agent binaries. Notably, - this is used by exploiters during propagation to retrieve the appropriate agent binary so that - it can be uploaded to a victim and executed. + IAgentBinaryRepository provides an interface for other components to access agent binaries. + Notably, this is used by exploiters during propagation to retrieve the appropriate agent binary + so that it can be uploaded to a victim and executed. """ @abc.abstractmethod diff --git a/monkey/infection_monkey/exploit/log4shell.py b/monkey/infection_monkey/exploit/log4shell.py index f511d75d9..fc925091b 100644 --- a/monkey/infection_monkey/exploit/log4shell.py +++ b/monkey/infection_monkey/exploit/log4shell.py @@ -79,7 +79,7 @@ class Log4ShellExploiter(WebRCE): def _start_agent_http_server(self, dropper_target_path) -> str: # Create server for http download and wait for it's startup. http_path, http_thread = HTTPTools.try_create_locked_transfer( - self.host, dropper_target_path, self.agent_repository + self.host, dropper_target_path, self.agent_binary_repository ) self._agent_http_server_thread = http_thread return http_path diff --git a/monkey/infection_monkey/exploit/mssqlexec.py b/monkey/infection_monkey/exploit/mssqlexec.py index 8e90365fb..6c155f468 100644 --- a/monkey/infection_monkey/exploit/mssqlexec.py +++ b/monkey/infection_monkey/exploit/mssqlexec.py @@ -147,7 +147,7 @@ class MSSQLExploiter(HostExploiter): def _start_agent_server(self, agent_path_on_victim: PureWindowsPath) -> LockedHTTPServer: self.agent_http_path, http_thread = HTTPTools.create_locked_transfer( - self.host, str(agent_path_on_victim), self.agent_repository + self.host, str(agent_path_on_victim), self.agent_binary_repository ) return http_thread diff --git a/monkey/infection_monkey/exploit/powershell.py b/monkey/infection_monkey/exploit/powershell.py index 268b2835d..d6b626f9f 100644 --- a/monkey/infection_monkey/exploit/powershell.py +++ b/monkey/infection_monkey/exploit/powershell.py @@ -163,7 +163,7 @@ class PowerShellExploiter(HostExploiter): temp_monkey_binary_filepath.unlink() def _create_local_agent_file(self, binary_path): - agent_binary_bytes = self.agent_repository.get_agent_binary(OperatingSystem.WINDOWS) + agent_binary_bytes = self.agent_binary_repository.get_agent_binary(OperatingSystem.WINDOWS) with open(binary_path, "wb") as f: f.write(agent_binary_bytes.getvalue()) diff --git a/monkey/infection_monkey/exploit/smbexec.py b/monkey/infection_monkey/exploit/smbexec.py index 84d477e98..80c09547f 100644 --- a/monkey/infection_monkey/exploit/smbexec.py +++ b/monkey/infection_monkey/exploit/smbexec.py @@ -30,7 +30,7 @@ class SMBExploiter(HostExploiter): SMB_SERVICE_NAME = "InfectionMonkey" def _exploit_host(self): - agent_binary = self.agent_repository.get_agent_binary(self.host.os["type"]) + agent_binary = self.agent_binary_repository.get_agent_binary(self.host.os["type"]) dest_path = get_agent_dst_path(self.host) creds = generate_brute_force_combinations(self.options["credentials"]) diff --git a/monkey/infection_monkey/exploit/sshexec.py b/monkey/infection_monkey/exploit/sshexec.py index a29cd8470..8b10c8c44 100644 --- a/monkey/infection_monkey/exploit/sshexec.py +++ b/monkey/infection_monkey/exploit/sshexec.py @@ -195,7 +195,9 @@ class SSHExploiter(HostExploiter): logger.error(self.exploit_result.error_message) return self.exploit_result - agent_binary_file_object = self.agent_repository.get_agent_binary(self.exploit_result.os) + agent_binary_file_object = self.agent_binary_repository.get_agent_binary( + self.exploit_result.os + ) if not agent_binary_file_object: self.exploit_result.error_message = ( diff --git a/monkey/infection_monkey/exploit/tools/http_tools.py b/monkey/infection_monkey/exploit/tools/http_tools.py index b27f6cf6f..a24fb909e 100644 --- a/monkey/infection_monkey/exploit/tools/http_tools.py +++ b/monkey/infection_monkey/exploit/tools/http_tools.py @@ -15,10 +15,10 @@ logger = logging.getLogger(__name__) class HTTPTools(object): @staticmethod def try_create_locked_transfer( - host, src_path, agent_repository, local_ip=None, local_port=None + host, src_path, agent_binary_repository, local_ip=None, local_port=None ): http_path, http_thread = HTTPTools.create_locked_transfer( - host, src_path, agent_repository, local_ip, local_port + host, src_path, agent_binary_repository, local_ip, local_port ) if not http_path: raise Exception("Http transfer creation failed.") @@ -27,13 +27,13 @@ class HTTPTools(object): @staticmethod def create_locked_transfer( - host, dropper_target_path, agent_repository, local_ip=None, local_port=None + host, dropper_target_path, agent_binary_repository, local_ip=None, local_port=None ) -> LockedHTTPServer: """ Create http server for file transfer with a lock :param host: Variable with target's information :param src_path: Monkey's path on current system - :param agent_repository: Repository to download Monkey agents + :param agent_binary_repository: Repository to download Monkey agents :param local_ip: IP where to host server :param local_port: Port at which to host monkey's download :return: Server address in http://%s:%s/%s format and LockedHTTPServer handler @@ -52,7 +52,12 @@ class HTTPTools(object): return None, None httpd = LockedHTTPServer( - local_ip, local_port, host.os["type"], dropper_target_path, agent_repository, lock + local_ip, + local_port, + host.os["type"], + dropper_target_path, + agent_binary_repository, + lock, ) httpd.start() lock.acquire() diff --git a/monkey/infection_monkey/exploit/web_rce.py b/monkey/infection_monkey/exploit/web_rce.py index a2a8ed2a6..4083aa928 100644 --- a/monkey/infection_monkey/exploit/web_rce.py +++ b/monkey/infection_monkey/exploit/web_rce.py @@ -295,7 +295,7 @@ class WebRCE(HostExploiter): dropper_target_path = self.monkey_target_paths[self.host.os["type"]] # Create server for http download and wait for it's startup. http_path, http_thread = HTTPTools.create_locked_transfer( - self.host, dropper_target_path, self.agent_repository + self.host, dropper_target_path, self.agent_binary_repository ) if not http_path: logger.debug("Exploiter failed, http transfer creation failed.") diff --git a/monkey/infection_monkey/exploit/wmiexec.py b/monkey/infection_monkey/exploit/wmiexec.py index 29605fb8d..cdbb3b63f 100644 --- a/monkey/infection_monkey/exploit/wmiexec.py +++ b/monkey/infection_monkey/exploit/wmiexec.py @@ -68,7 +68,7 @@ class WmiExploiter(HostExploiter): self.report_login_attempt(True, user, password, lm_hash, ntlm_hash) self.exploit_result.exploitation_success = True - downloaded_agent = self.agent_repository.get_agent_binary(self.host.os["type"]) + downloaded_agent = self.agent_binary_repository.get_agent_binary(self.host.os["type"]) if self._is_interrupted(): self._set_interrupted() diff --git a/monkey/infection_monkey/monkey.py b/monkey/infection_monkey/monkey.py index 115b67e24..02e6b57ad 100644 --- a/monkey/infection_monkey/monkey.py +++ b/monkey/infection_monkey/monkey.py @@ -27,7 +27,7 @@ from infection_monkey.credential_repository import ( IPropagationCredentialsRepository, add_credentials_from_event_to_propagation_credentials_repository, ) -from infection_monkey.exploit import CachingAgentRepository, ExploiterWrapper +from infection_monkey.exploit import CachingAgentBinaryRepository, ExploiterWrapper from infection_monkey.exploit.hadoop import HadoopExploiter from infection_monkey.exploit.log4shell import Log4ShellExploiter from infection_monkey.exploit.mssqlexec import MSSQLExploiter @@ -270,10 +270,12 @@ class InfectionMonkey: puppet.load_plugin("smb", SMBFingerprinter(), PluginType.FINGERPRINTER) puppet.load_plugin("ssh", SSHFingerprinter(), PluginType.FINGERPRINTER) - agent_repository = CachingAgentRepository( + agent_binary_repository = CachingAgentBinaryRepository( f"https://{self._control_client.server_address}", self._control_client.proxies ) - exploit_wrapper = ExploiterWrapper(self._telemetry_messenger, event_queue, agent_repository) + exploit_wrapper = ExploiterWrapper( + self._telemetry_messenger, event_queue, agent_binary_repository + ) puppet.load_plugin( "HadoopExploiter", exploit_wrapper.wrap(HadoopExploiter), PluginType.EXPLOITER diff --git a/monkey/infection_monkey/transport/http.py b/monkey/infection_monkey/transport/http.py index 7bcbcd87d..46dad8c52 100644 --- a/monkey/infection_monkey/transport/http.py +++ b/monkey/infection_monkey/transport/http.py @@ -19,7 +19,7 @@ logger = getLogger(__name__) class FileServHTTPRequestHandler(http.server.BaseHTTPRequestHandler): protocol_version = "HTTP/1.1" victim_os = "" - agent_repository = None + agent_binary_repository = None def version_string(self): return "Microsoft-IIS/7.5." @@ -66,7 +66,7 @@ class FileServHTTPRequestHandler(http.server.BaseHTTPRequestHandler): self.send_error(500, "") return None, 0, 0 try: - f = self.agent_repository.get_agent_binary(self.victim_os) + f = self.agent_binary_repository.get_agent_binary(self.victim_os) except IOError: self.send_error(404, "File not found") return None, 0, 0 @@ -178,7 +178,7 @@ class LockedHTTPServer(threading.Thread): local_port, victim_os, dropper_target_path, - agent_repository, + agent_binary_repository, lock, max_downloads=1, ): @@ -186,7 +186,7 @@ class LockedHTTPServer(threading.Thread): self._local_port = local_port self._victim_os = victim_os self._dropper_target_path = dropper_target_path - self._agent_repository = agent_repository + self._agent_binary_repository = agent_binary_repository self.max_downloads = max_downloads self.downloads = 0 self._stopped = False @@ -200,7 +200,7 @@ class LockedHTTPServer(threading.Thread): from infection_monkey.telemetry.attack.t1105_telem import T1105Telem victim_os = self._victim_os - agent_repository = self._agent_repository + agent_binary_repository = self._agent_binary_repository @staticmethod def report_download(dest=None): diff --git a/monkey/tests/unit_tests/infection_monkey/exploit/test_powershell.py b/monkey/tests/unit_tests/infection_monkey/exploit/test_powershell.py index a764de832..bf388d6a9 100644 --- a/monkey/tests/unit_tests/infection_monkey/exploit/test_powershell.py +++ b/monkey/tests/unit_tests/infection_monkey/exploit/test_powershell.py @@ -17,8 +17,8 @@ LM_HASH_LIST = ["bogo_lm_1"] NT_HASH_LIST = ["bogo_nt_1", "bogo_nt_2"] -mock_agent_repository = MagicMock() -mock_agent_repository.get_agent_binary.return_value = BytesIO(b"BINARY_EXECUTABLE") +mock_agent_binary_repository = MagicMock() +mock_agent_binary_repository.get_agent_binary.return_value = BytesIO(b"BINARY_EXECUTABLE") @pytest.fixture @@ -37,7 +37,7 @@ def powershell_arguments(http_and_https_both_enabled_host): "current_depth": 2, "telemetry_messenger": MagicMock(), "event_queue": MagicMock(), - "agent_repository": mock_agent_repository, + "agent_binary_repository": mock_agent_binary_repository, "interrupt": threading.Event(), } return arguments