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.
This commit is contained in:
Mike Salvatore 2021-07-30 04:55:45 -04:00
parent 017e37deb0
commit e7d694380d
2 changed files with 26 additions and 27 deletions

View File

@ -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"
}
}
}

View File

@ -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")