From e7d694380dbd0d4314c29230598881a2e24cc0cc Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Fri, 30 Jul 2021 04:55:45 -0400 Subject: [PATCH] Agent: Skip propagation if max depth is reached Fixes #1374 When monkey starts, it launches a thread for executing post breach actions. It then executes its propagation loop on the main thread. If the maximum propagation depth has been reached, a PlannedShutdownException is raised on the main thread. This results in InfectionMonkey.cleanup() being called, which then calls InfectionMonkey.self_delete(). self_delete() deletes the monkey binary, but the post breach actions thread hasn't been stopped, resulting in a trace when the thread attempts an import. We don't need to shutdown if the maximum propagation depth is reached. We only need to skip the propagation phase so that monkey does not propagate further. PBAs and payloads can still be allowed to run. --- .swm/AzD8XysWg1BBXCjCDkfq.swm | 31 +++++++++++++++---------------- monkey/infection_monkey/monkey.py | 22 +++++++++++----------- 2 files changed, 26 insertions(+), 27 deletions(-) diff --git a/.swm/AzD8XysWg1BBXCjCDkfq.swm b/.swm/AzD8XysWg1BBXCjCDkfq.swm index 5383db0b7..29ad78526 100644 --- a/.swm/AzD8XysWg1BBXCjCDkfq.swm +++ b/.swm/AzD8XysWg1BBXCjCDkfq.swm @@ -17,7 +17,7 @@ "type": "snippet", "path": "monkey/infection_monkey/config.py", "comments": [], - "firstLineNumber": 126, + "firstLineNumber": 124, "lines": [ " exploiter_classes = []", " system_info_collector_classes = []", @@ -33,19 +33,18 @@ "type": "snippet", "path": "monkey/infection_monkey/monkey.py", "comments": [], - "firstLineNumber": 159, + "firstLineNumber": 220, "lines": [ + " if not self._keep_running or not WormConfiguration.alive:", + " break", " ", - " if not self._keep_running or not WormConfiguration.alive:", - " break", - "*", - "* machines = self._network.get_victim_machines(", - "* max_find=WormConfiguration.victims_max_find,", - "* stop_callback=ControlClient.check_for_stop,", - "* )", - " is_empty = True", - " for machine in machines:", - " if ControlClient.check_for_stop():" + "* machines = self._network.get_victim_machines(", + "* max_find=WormConfiguration.victims_max_find,", + "* stop_callback=ControlClient.check_for_stop,", + "* )", + " is_empty = True", + " for machine in machines:", + " if ControlClient.check_for_stop():" ] }, { @@ -77,11 +76,11 @@ "symbols": {}, "file_version": "2.0.1", "meta": { - "app_version": "0.4.1-1", + "app_version": "0.4.9-1", "file_blobs": { - "monkey/infection_monkey/config.py": "ffdea551eb1ae2b65d4700db896c746771e7954c", - "monkey/infection_monkey/monkey.py": "c81a6251746e3af4e93eaa7d50af44d33debe05c", - "monkey/monkey_island/cc/services/config_schema/internal.py": "d03527b89c21dfb832a15e4f7d55f4027d83b453" + "monkey/infection_monkey/config.py": "0bede1c57949987f5c8025bd9b8f7aa29d02a6af", + "monkey/infection_monkey/monkey.py": "89d2fa8452dee70f6d2985a9bb452f0159ea8219", + "monkey/monkey_island/cc/services/config_schema/internal.py": "1ce1c864b1df332b65e16b4ce9ed533affd73f9c" } } } diff --git a/monkey/infection_monkey/monkey.py b/monkey/infection_monkey/monkey.py index 5b0b1bafd..5c2cdf5eb 100644 --- a/monkey/infection_monkey/monkey.py +++ b/monkey/infection_monkey/monkey.py @@ -40,7 +40,7 @@ from infection_monkey.utils.monkey_dir import ( from infection_monkey.utils.monkey_log_path import get_monkey_log_path from infection_monkey.windows_upgrader import WindowsUpgrader -MAX_DEPTH_REACHED_MESSAGE = "Reached max depth, shutting down" +MAX_DEPTH_REACHED_MESSAGE = "Reached max depth, skipping propagation phase." LOG = logging.getLogger(__name__) @@ -147,10 +147,13 @@ class InfectionMonkey(object): post_breach_phase = Thread(target=self.start_post_breach_phase) post_breach_phase.start() - LOG.debug("Starting the propagation phase.") - self.shutdown_by_max_depth_reached() - - self.propagate() + if not InfectionMonkey.max_propagation_depth_reached(): + LOG.info("Starting the propagation phase.") + LOG.debug("Running with depth: %d" % WormConfiguration.depth) + self.propagate() + else: + LOG.info("Maximum propagation depth has been reached; monkey will not propagate.") + TraceTelem(MAX_DEPTH_REACHED_MESSAGE).send() InfectionMonkey.run_ransomware() @@ -181,12 +184,9 @@ class InfectionMonkey(object): self.collect_system_info_if_configured() PostBreach().execute_all_configured() - def shutdown_by_max_depth_reached(self): - if 0 == WormConfiguration.depth: - TraceTelem(MAX_DEPTH_REACHED_MESSAGE).send() - raise PlannedShutdownException(MAX_DEPTH_REACHED_MESSAGE) - else: - LOG.debug("Running with depth: %d" % WormConfiguration.depth) + @staticmethod + def max_propagation_depth_reached(): + return 0 == WormConfiguration.depth def collect_system_info_if_configured(self): LOG.debug("Calling for system info collection")