From df77ca4f96f84a00f3c2e9eaec7b905667674d3f Mon Sep 17 00:00:00 2001 From: vakarisz Date: Mon, 20 Jun 2022 15:52:50 +0300 Subject: [PATCH 01/14] Agent: Change the logic of depth to represent current depth Based on the previous logic the depth parameter represented hops remaining, not current depth. --- monkey/infection_monkey/config.py | 2 +- monkey/infection_monkey/exploit/hadoop.py | 2 +- monkey/infection_monkey/exploit/log4shell.py | 2 +- monkey/infection_monkey/exploit/mssqlexec.py | 2 +- monkey/infection_monkey/exploit/powershell.py | 2 +- monkey/infection_monkey/exploit/smbexec.py | 4 ++-- monkey/infection_monkey/exploit/sshexec.py | 2 +- monkey/infection_monkey/exploit/web_rce.py | 4 ++-- monkey/infection_monkey/exploit/wmiexec.py | 4 ++-- monkey/infection_monkey/master/automated_master.py | 4 ++-- monkey/infection_monkey/monkey.py | 10 ++-------- monkey/infection_monkey/utils/commands.py | 2 -- .../unit_tests/infection_monkey/utils/test_commands.py | 10 ---------- 13 files changed, 16 insertions(+), 34 deletions(-) diff --git a/monkey/infection_monkey/config.py b/monkey/infection_monkey/config.py index 8e783dbf5..fe6106aed 100644 --- a/monkey/infection_monkey/config.py +++ b/monkey/infection_monkey/config.py @@ -60,7 +60,7 @@ class Configuration(object): ########################### # depth of propagation - depth = 2 + depth = 0 max_depth = None keep_tunnel_open_time = 30 diff --git a/monkey/infection_monkey/exploit/hadoop.py b/monkey/infection_monkey/exploit/hadoop.py index 15e801452..8bafa6969 100644 --- a/monkey/infection_monkey/exploit/hadoop.py +++ b/monkey/infection_monkey/exploit/hadoop.py @@ -104,7 +104,7 @@ class HadoopExploiter(WebRCE): def _build_command(self, path, http_path): # Build command to execute - monkey_cmd = build_monkey_commandline(self.host, self.current_depth - 1) + monkey_cmd = build_monkey_commandline(self.host, self.current_depth + 1) if "linux" in self.host.os["type"]: base_command = HADOOP_LINUX_COMMAND else: diff --git a/monkey/infection_monkey/exploit/log4shell.py b/monkey/infection_monkey/exploit/log4shell.py index 198635976..077c7c865 100644 --- a/monkey/infection_monkey/exploit/log4shell.py +++ b/monkey/infection_monkey/exploit/log4shell.py @@ -114,7 +114,7 @@ class Log4ShellExploiter(WebRCE): def _build_command(self, path: PurePath, http_path) -> str: # Build command to execute - monkey_cmd = build_monkey_commandline(self.host, self.current_depth - 1, location=path) + monkey_cmd = build_monkey_commandline(self.host, self.current_depth + 1, location=path) if "linux" in self.host.os["type"]: base_command = LOG4SHELL_LINUX_COMMAND else: diff --git a/monkey/infection_monkey/exploit/mssqlexec.py b/monkey/infection_monkey/exploit/mssqlexec.py index 75c369ecf..8e90365fb 100644 --- a/monkey/infection_monkey/exploit/mssqlexec.py +++ b/monkey/infection_monkey/exploit/mssqlexec.py @@ -178,7 +178,7 @@ class MSSQLExploiter(HostExploiter): def _build_agent_launch_command(self, agent_path_on_victim: PureWindowsPath) -> str: agent_args = build_monkey_commandline( - self.host, self.current_depth - 1, agent_path_on_victim + self.host, self.current_depth + 1, agent_path_on_victim ) return f"{agent_path_on_victim} {DROPPER_ARG} {agent_args}" diff --git a/monkey/infection_monkey/exploit/powershell.py b/monkey/infection_monkey/exploit/powershell.py index 7b33df9ed..6ef72963e 100644 --- a/monkey/infection_monkey/exploit/powershell.py +++ b/monkey/infection_monkey/exploit/powershell.py @@ -168,7 +168,7 @@ class PowerShellExploiter(HostExploiter): def _run_monkey_executable_on_victim(self, executable_path): monkey_execution_command = build_monkey_execution_command( - self.host, self.current_depth - 1, executable_path + self.host, self.current_depth + 1, executable_path ) logger.info( diff --git a/monkey/infection_monkey/exploit/smbexec.py b/monkey/infection_monkey/exploit/smbexec.py index 03b6bfb3e..84d477e98 100644 --- a/monkey/infection_monkey/exploit/smbexec.py +++ b/monkey/infection_monkey/exploit/smbexec.py @@ -91,13 +91,13 @@ class SMBExploiter(HostExploiter): "dropper_path": remote_full_path } + build_monkey_commandline( self.host, - self.current_depth - 1, + self.current_depth + 1, str(dest_path), ) else: cmdline = MONKEY_CMDLINE_DETACHED_WINDOWS % { "monkey_path": remote_full_path - } + build_monkey_commandline(self.host, self.current_depth - 1) + } + build_monkey_commandline(self.host, self.current_depth + 1) smb_conn = None for str_bind_format, port in SMBExploiter.KNOWN_PROTOCOLS.values(): diff --git a/monkey/infection_monkey/exploit/sshexec.py b/monkey/infection_monkey/exploit/sshexec.py index f76147fd1..a29cd8470 100644 --- a/monkey/infection_monkey/exploit/sshexec.py +++ b/monkey/infection_monkey/exploit/sshexec.py @@ -242,7 +242,7 @@ class SSHExploiter(HostExploiter): try: cmdline = f"{monkey_path_on_victim} {MONKEY_ARG}" - cmdline += build_monkey_commandline(self.host, self.current_depth - 1) + cmdline += build_monkey_commandline(self.host, self.current_depth + 1) cmdline += " > /dev/null 2>&1 &" ssh.exec_command(cmdline, timeout=SSH_EXEC_TIMEOUT) diff --git a/monkey/infection_monkey/exploit/web_rce.py b/monkey/infection_monkey/exploit/web_rce.py index 957ed361d..99438a0a7 100644 --- a/monkey/infection_monkey/exploit/web_rce.py +++ b/monkey/infection_monkey/exploit/web_rce.py @@ -369,14 +369,14 @@ class WebRCE(HostExploiter): default_path = self.get_default_dropper_path() if default_path is False: return False - monkey_cmd = build_monkey_commandline(self.host, self.current_depth - 1, default_path) + monkey_cmd = build_monkey_commandline(self.host, self.current_depth + 1, default_path) command = RUN_MONKEY % { "monkey_path": path, "monkey_type": DROPPER_ARG, "parameters": monkey_cmd, } else: - monkey_cmd = build_monkey_commandline(self.host, self.current_depth - 1) + monkey_cmd = build_monkey_commandline(self.host, self.current_depth + 1) command = RUN_MONKEY % { "monkey_path": path, "monkey_type": MONKEY_ARG, diff --git a/monkey/infection_monkey/exploit/wmiexec.py b/monkey/infection_monkey/exploit/wmiexec.py index b8d577365..29605fb8d 100644 --- a/monkey/infection_monkey/exploit/wmiexec.py +++ b/monkey/infection_monkey/exploit/wmiexec.py @@ -96,13 +96,13 @@ class WmiExploiter(HostExploiter): "dropper_path": remote_full_path } + build_monkey_commandline( self.host, - self.current_depth - 1, + self.current_depth + 1, DROPPER_TARGET_PATH_WIN64, ) else: cmdline = MONKEY_CMDLINE_WINDOWS % { "monkey_path": remote_full_path - } + build_monkey_commandline(self.host, self.current_depth - 1) + } + build_monkey_commandline(self.host, self.current_depth + 1) # execute the remote monkey result = WmiTools.get_object(wmi_connection, "Win32_Process").Create( diff --git a/monkey/infection_monkey/master/automated_master.py b/monkey/infection_monkey/master/automated_master.py index 26de7227e..51f675d11 100644 --- a/monkey/infection_monkey/master/automated_master.py +++ b/monkey/infection_monkey/master/automated_master.py @@ -169,10 +169,10 @@ class AutomatedMaster(IMaster): # still running. credential_collector_thread.join() - current_depth = self._current_depth if self._current_depth is not None else config["depth"] + current_depth = self._current_depth if self._current_depth is not None else 0 logger.info(f"Current depth is {current_depth}") - if self._can_propagate() and current_depth > 0: + if self._can_propagate() and current_depth < config["depth"]: self._propagator.propagate(config["propagation"], current_depth, self._stop) payload_thread = create_daemon_thread( diff --git a/monkey/infection_monkey/monkey.py b/monkey/infection_monkey/monkey.py index d7a051193..4eeec8b76 100644 --- a/monkey/infection_monkey/monkey.py +++ b/monkey/infection_monkey/monkey.py @@ -166,7 +166,7 @@ class InfectionMonkey: firewall.add_firewall_rule() self._monkey_inbound_tunnel = self._control_client.create_control_tunnel() - if self._monkey_inbound_tunnel and self._propagation_enabled(): + if self._monkey_inbound_tunnel: self._monkey_inbound_tunnel.start() StateTelem(is_done=False, version=get_version()).send() @@ -353,7 +353,7 @@ class InfectionMonkey: reset_signal_handlers() - if self._monkey_inbound_tunnel and self._propagation_enabled(): + if self._monkey_inbound_tunnel: self._monkey_inbound_tunnel.stop() self._monkey_inbound_tunnel.join() @@ -378,12 +378,6 @@ class InfectionMonkey: logger.info("Monkey is shutting down") - def _propagation_enabled(self) -> bool: - # If self._current_depth is None, assume that propagation is desired. - # The Master will ignore this value if it is None and pull the actual - # maximum depth from the server - return self._current_depth is None or self._current_depth > 0 - def _close_tunnel(self): tunnel_address = ( self._control_client.proxies.get("https", "").replace("http://", "").split(":")[0] diff --git a/monkey/infection_monkey/utils/commands.py b/monkey/infection_monkey/utils/commands.py index ddd07dc8d..b66a622e9 100644 --- a/monkey/infection_monkey/utils/commands.py +++ b/monkey/infection_monkey/utils/commands.py @@ -40,8 +40,6 @@ def build_monkey_commandline_explicitly( cmdline.append("-s") cmdline.append(str(server)) if depth is not None: - if int(depth) < 0: - depth = 0 cmdline.append("-d") cmdline.append(str(depth)) if location is not None: diff --git a/monkey/tests/unit_tests/infection_monkey/utils/test_commands.py b/monkey/tests/unit_tests/infection_monkey/utils/test_commands.py index db9ddbbe7..bbd27274e 100644 --- a/monkey/tests/unit_tests/infection_monkey/utils/test_commands.py +++ b/monkey/tests/unit_tests/infection_monkey/utils/test_commands.py @@ -28,16 +28,6 @@ def test_build_monkey_commandline_explicitly_arguments(): assert expected == actual -def test_build_monkey_commandline_explicitly_depth_condition_less(): - expected = [ - "-d", - "0", - ] - actual = build_monkey_commandline_explicitly(depth=-50) - - assert expected == actual - - def test_build_monkey_commandline_explicitly_depth_condition_greater(): expected = [ "-d", From 8df92640de2af32d9a0754598ea894f337e7acc4 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Mon, 20 Jun 2022 16:00:53 +0300 Subject: [PATCH 02/14] Changelog: Add entry about changed behaviour of depth param --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ac3f6ca24..ce0dd381f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,8 @@ Changelog](https://keepachangelog.com/en/1.0.0/). - Update MongoDB version to 4.4.x. #1924 - Endpoint to get agent binaries from "/api/agent/download/" to "/api/agent-binaries/". #1978 +- Depth flag (-d) on the agent now acts the way you would expect(it represents + the current depth of the agent, not hops remaining). #2033 - Agent configuration structure. #1996, #1998, #1961, #1997, #1994, #1741, #1761, #1695, #1605, #2028 From 3c2d58b5d3a10c83eb6c25039b1111d47fd23200 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Wed, 22 Jun 2022 11:52:36 +0300 Subject: [PATCH 03/14] Agent, Common: Add positive_int argument type --- monkey/common/utils/argparse_types.py | 9 +++++++++ monkey/infection_monkey/dropper.py | 3 ++- monkey/infection_monkey/monkey.py | 3 ++- 3 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 monkey/common/utils/argparse_types.py diff --git a/monkey/common/utils/argparse_types.py b/monkey/common/utils/argparse_types.py new file mode 100644 index 000000000..a920ef1b4 --- /dev/null +++ b/monkey/common/utils/argparse_types.py @@ -0,0 +1,9 @@ +import argparse + + +def positive_int(_input: str): + int_value = int(_input) + if int_value <= 0: + raise argparse.ArgumentTypeError(f"{_input} is not a positive integer") + + return int_value diff --git a/monkey/infection_monkey/dropper.py b/monkey/infection_monkey/dropper.py index 8e5fb0f5c..48e5bb86d 100644 --- a/monkey/infection_monkey/dropper.py +++ b/monkey/infection_monkey/dropper.py @@ -9,6 +9,7 @@ import sys import time from pathlib import PosixPath, WindowsPath +from common.utils.argparse_types import positive_int from common.utils.attack_utils import UsageEnum from infection_monkey.utils.commands import ( build_monkey_commandline_explicitly, @@ -45,7 +46,7 @@ class MonkeyDrops(object): arg_parser.add_argument("-p", "--parent") arg_parser.add_argument("-t", "--tunnel") arg_parser.add_argument("-s", "--server") - arg_parser.add_argument("-d", "--depth", type=int) + arg_parser.add_argument("-d", "--depth", type=positive_int) arg_parser.add_argument("-l", "--location") arg_parser.add_argument("-vp", "--vulnerable-port") self.opts = arg_parser.parse_args(args) diff --git a/monkey/infection_monkey/monkey.py b/monkey/infection_monkey/monkey.py index 4eeec8b76..6e3d9b0f0 100644 --- a/monkey/infection_monkey/monkey.py +++ b/monkey/infection_monkey/monkey.py @@ -8,6 +8,7 @@ from typing import List import infection_monkey.tunnel as tunnel from common.network.network_utils import address_to_ip_port +from common.utils.argparse_types import positive_int from common.utils.attack_utils import ScanStatus, UsageEnum from common.version import get_version from infection_monkey.config import GUID @@ -104,7 +105,7 @@ class InfectionMonkey: arg_parser.add_argument("-p", "--parent") arg_parser.add_argument("-t", "--tunnel") arg_parser.add_argument("-s", "--server") - arg_parser.add_argument("-d", "--depth", type=int) + arg_parser.add_argument("-d", "--depth", type=positive_int) opts = arg_parser.parse_args(args) InfectionMonkey._log_arguments(opts) From 582328bea875ef5f3ed761ebeccf8a0208a5b11f Mon Sep 17 00:00:00 2001 From: vakarisz Date: Wed, 22 Jun 2022 12:31:47 +0300 Subject: [PATCH 04/14] Agent: Create and use should_propagate method This method is used to determine if the inbound tunnel should be open and if the master should attempt exploiting other machines --- monkey/infection_monkey/master/automated_master.py | 5 +++-- monkey/infection_monkey/monkey.py | 6 +++++- monkey/infection_monkey/utils/propagation.py | 2 ++ 3 files changed, 10 insertions(+), 3 deletions(-) create mode 100644 monkey/infection_monkey/utils/propagation.py diff --git a/monkey/infection_monkey/master/automated_master.py b/monkey/infection_monkey/master/automated_master.py index 51f675d11..780e07b6f 100644 --- a/monkey/infection_monkey/master/automated_master.py +++ b/monkey/infection_monkey/master/automated_master.py @@ -14,6 +14,7 @@ from infection_monkey.telemetry.credentials_telem import CredentialsTelem from infection_monkey.telemetry.messengers.i_telemetry_messenger import ITelemetryMessenger from infection_monkey.telemetry.post_breach_telem import PostBreachTelem from infection_monkey.utils.threading import create_daemon_thread, interruptible_iter +from utils.propagation import should_propagate from . import Exploiter, IPScanner, Propagator from .option_parsing import custom_pba_is_enabled @@ -172,7 +173,7 @@ class AutomatedMaster(IMaster): current_depth = self._current_depth if self._current_depth is not None else 0 logger.info(f"Current depth is {current_depth}") - if self._can_propagate() and current_depth < config["depth"]: + if self._can_propagate(): self._propagator.propagate(config["propagation"], current_depth, self._stop) payload_thread = create_daemon_thread( @@ -201,7 +202,7 @@ class AutomatedMaster(IMaster): self._telemetry_messenger.send_telemetry(PostBreachTelem(pba_data)) def _can_propagate(self) -> bool: - return True + return should_propagate(self._control_channel.get_config(), self._current_depth) def _run_payload(self, payload: Tuple[str, Dict]): name = payload[0] diff --git a/monkey/infection_monkey/monkey.py b/monkey/infection_monkey/monkey.py index 6e3d9b0f0..8b8d8e600 100644 --- a/monkey/infection_monkey/monkey.py +++ b/monkey/infection_monkey/monkey.py @@ -79,6 +79,7 @@ from infection_monkey.utils.monkey_dir import ( ) from infection_monkey.utils.monkey_log_path import get_agent_log_path from infection_monkey.utils.signal_handler import register_signal_handlers, reset_signal_handlers +from utils.propagation import should_propagate logger = logging.getLogger(__name__) logging.getLogger("urllib3").setLevel(logging.INFO) @@ -167,7 +168,10 @@ class InfectionMonkey: firewall.add_firewall_rule() self._monkey_inbound_tunnel = self._control_client.create_control_tunnel() - if self._monkey_inbound_tunnel: + config = ControlChannel( + self._control_client.server_address, GUID, self._control_client.proxies + ).get_config() + if self._monkey_inbound_tunnel and should_propagate(config, self._current_depth): self._monkey_inbound_tunnel.start() StateTelem(is_done=False, version=get_version()).send() diff --git a/monkey/infection_monkey/utils/propagation.py b/monkey/infection_monkey/utils/propagation.py new file mode 100644 index 000000000..568def5d5 --- /dev/null +++ b/monkey/infection_monkey/utils/propagation.py @@ -0,0 +1,2 @@ +def should_propagate(config: dict, depth: int) -> bool: + return config["config"]["depth"] < depth From 734fc80c92bcec76efd82e9e54dd28e323279771 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Wed, 22 Jun 2022 13:04:24 +0300 Subject: [PATCH 05/14] Agent: Add logging message about maximum depth reached --- monkey/infection_monkey/master/automated_master.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/monkey/infection_monkey/master/automated_master.py b/monkey/infection_monkey/master/automated_master.py index 780e07b6f..7fd943932 100644 --- a/monkey/infection_monkey/master/automated_master.py +++ b/monkey/infection_monkey/master/automated_master.py @@ -3,6 +3,8 @@ import threading import time from typing import Any, Callable, Dict, Iterable, List, Mapping, Optional, Tuple +from utils.propagation import should_propagate + from common.utils import Timer from infection_monkey.credential_store import ICredentialsStore from infection_monkey.i_control_channel import IControlChannel, IslandCommunicationError @@ -14,7 +16,6 @@ from infection_monkey.telemetry.credentials_telem import CredentialsTelem from infection_monkey.telemetry.messengers.i_telemetry_messenger import ITelemetryMessenger from infection_monkey.telemetry.post_breach_telem import PostBreachTelem from infection_monkey.utils.threading import create_daemon_thread, interruptible_iter -from utils.propagation import should_propagate from . import Exploiter, IPScanner, Propagator from .option_parsing import custom_pba_is_enabled @@ -175,6 +176,8 @@ class AutomatedMaster(IMaster): if self._can_propagate(): self._propagator.propagate(config["propagation"], current_depth, self._stop) + else: + logger.info("Skipping propagation, maximum depth reached") payload_thread = create_daemon_thread( target=self._run_plugins, From 5a48bfcfcc6e39d24f6e82374cc0942d67440214 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Wed, 22 Jun 2022 14:04:15 +0300 Subject: [PATCH 06/14] Agent: Fix should_propagate import in automated_master.py --- monkey/infection_monkey/master/automated_master.py | 3 +-- monkey/infection_monkey/monkey.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/monkey/infection_monkey/master/automated_master.py b/monkey/infection_monkey/master/automated_master.py index 7fd943932..1873ecea0 100644 --- a/monkey/infection_monkey/master/automated_master.py +++ b/monkey/infection_monkey/master/automated_master.py @@ -3,8 +3,6 @@ import threading import time from typing import Any, Callable, Dict, Iterable, List, Mapping, Optional, Tuple -from utils.propagation import should_propagate - from common.utils import Timer from infection_monkey.credential_store import ICredentialsStore from infection_monkey.i_control_channel import IControlChannel, IslandCommunicationError @@ -15,6 +13,7 @@ from infection_monkey.network import NetworkInterface from infection_monkey.telemetry.credentials_telem import CredentialsTelem from infection_monkey.telemetry.messengers.i_telemetry_messenger import ITelemetryMessenger from infection_monkey.telemetry.post_breach_telem import PostBreachTelem +from infection_monkey.utils.propagation import should_propagate from infection_monkey.utils.threading import create_daemon_thread, interruptible_iter from . import Exploiter, IPScanner, Propagator diff --git a/monkey/infection_monkey/monkey.py b/monkey/infection_monkey/monkey.py index 8b8d8e600..e02e4e2eb 100644 --- a/monkey/infection_monkey/monkey.py +++ b/monkey/infection_monkey/monkey.py @@ -78,8 +78,8 @@ from infection_monkey.utils.monkey_dir import ( remove_monkey_dir, ) from infection_monkey.utils.monkey_log_path import get_agent_log_path +from infection_monkey.utils.propagation import should_propagate from infection_monkey.utils.signal_handler import register_signal_handlers, reset_signal_handlers -from utils.propagation import should_propagate logger = logging.getLogger(__name__) logging.getLogger("urllib3").setLevel(logging.INFO) From 552e2100faa767f13f5e9fd1227e64416814c5c1 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Wed, 22 Jun 2022 14:33:47 +0300 Subject: [PATCH 07/14] Agent: Set default depth cmd parameter to 0 If user runs the agent it should start with depth 0, because usually it means that it's running on the island --- monkey/infection_monkey/dropper.py | 2 +- monkey/infection_monkey/monkey.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/monkey/infection_monkey/dropper.py b/monkey/infection_monkey/dropper.py index 48e5bb86d..3ba310492 100644 --- a/monkey/infection_monkey/dropper.py +++ b/monkey/infection_monkey/dropper.py @@ -46,7 +46,7 @@ class MonkeyDrops(object): arg_parser.add_argument("-p", "--parent") arg_parser.add_argument("-t", "--tunnel") arg_parser.add_argument("-s", "--server") - arg_parser.add_argument("-d", "--depth", type=positive_int) + arg_parser.add_argument("-d", "--depth", type=positive_int, default=0) arg_parser.add_argument("-l", "--location") arg_parser.add_argument("-vp", "--vulnerable-port") self.opts = arg_parser.parse_args(args) diff --git a/monkey/infection_monkey/monkey.py b/monkey/infection_monkey/monkey.py index e02e4e2eb..d91f28018 100644 --- a/monkey/infection_monkey/monkey.py +++ b/monkey/infection_monkey/monkey.py @@ -106,7 +106,7 @@ class InfectionMonkey: arg_parser.add_argument("-p", "--parent") arg_parser.add_argument("-t", "--tunnel") arg_parser.add_argument("-s", "--server") - arg_parser.add_argument("-d", "--depth", type=positive_int) + arg_parser.add_argument("-d", "--depth", type=positive_int, default=0) opts = arg_parser.parse_args(args) InfectionMonkey._log_arguments(opts) From e15206101a49a13769685dcb96404d9e9adc82ee Mon Sep 17 00:00:00 2001 From: vakarisz Date: Wed, 22 Jun 2022 14:42:19 +0300 Subject: [PATCH 08/14] Agent: Fix a bug in should_propagate --- monkey/infection_monkey/utils/propagation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monkey/infection_monkey/utils/propagation.py b/monkey/infection_monkey/utils/propagation.py index 568def5d5..ed9567c26 100644 --- a/monkey/infection_monkey/utils/propagation.py +++ b/monkey/infection_monkey/utils/propagation.py @@ -1,2 +1,2 @@ def should_propagate(config: dict, depth: int) -> bool: - return config["config"]["depth"] < depth + return config["config"]["depth"] > depth From 27bff7e41c30a315b3e4bc2c89b421216bcfa7e6 Mon Sep 17 00:00:00 2001 From: vakaris_zilius Date: Wed, 22 Jun 2022 12:40:55 +0000 Subject: [PATCH 09/14] Island: Remove updating agent configuration with stolen credentials --- monkey/infection_monkey/master/automated_master.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/monkey/infection_monkey/master/automated_master.py b/monkey/infection_monkey/master/automated_master.py index 1873ecea0..4d2cb3902 100644 --- a/monkey/infection_monkey/master/automated_master.py +++ b/monkey/infection_monkey/master/automated_master.py @@ -173,7 +173,7 @@ class AutomatedMaster(IMaster): current_depth = self._current_depth if self._current_depth is not None else 0 logger.info(f"Current depth is {current_depth}") - if self._can_propagate(): + if should_propagate(self._control_channel.get_config(), self._current_depth): self._propagator.propagate(config["propagation"], current_depth, self._stop) else: logger.info("Skipping propagation, maximum depth reached") @@ -203,9 +203,6 @@ class AutomatedMaster(IMaster): for pba_data in self._puppet.run_pba(name, options): self._telemetry_messenger.send_telemetry(PostBreachTelem(pba_data)) - def _can_propagate(self) -> bool: - return should_propagate(self._control_channel.get_config(), self._current_depth) - def _run_payload(self, payload: Tuple[str, Dict]): name = payload[0] options = payload[1] From f0029a0d824a327402bab1d3417f7b9e7cc3c1fa Mon Sep 17 00:00:00 2001 From: vakaris_zilius Date: Wed, 22 Jun 2022 13:13:32 +0000 Subject: [PATCH 10/14] Agent: Close inbound tunnel if one was opened --- monkey/infection_monkey/monkey.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/monkey/infection_monkey/monkey.py b/monkey/infection_monkey/monkey.py index d91f28018..53d8f8662 100644 --- a/monkey/infection_monkey/monkey.py +++ b/monkey/infection_monkey/monkey.py @@ -99,6 +99,7 @@ class InfectionMonkey: self._telemetry_messenger = LegacyTelemetryMessengerAdapter() self._current_depth = self._opts.depth self._master = None + self._inbound_tunnel_opened = False @staticmethod def _get_arguments(args): @@ -172,6 +173,7 @@ class InfectionMonkey: self._control_client.server_address, GUID, self._control_client.proxies ).get_config() if self._monkey_inbound_tunnel and should_propagate(config, self._current_depth): + self._inbound_tunnel_opened = True self._monkey_inbound_tunnel.start() StateTelem(is_done=False, version=get_version()).send() @@ -358,7 +360,7 @@ class InfectionMonkey: reset_signal_handlers() - if self._monkey_inbound_tunnel: + if self._inbound_tunnel_opened: self._monkey_inbound_tunnel.stop() self._monkey_inbound_tunnel.join() From 8358253fc76bdb92bd9981e45022f10000b062f3 Mon Sep 17 00:00:00 2001 From: vakaris_zilius Date: Wed, 22 Jun 2022 13:14:24 +0000 Subject: [PATCH 11/14] Agent: Rename depth to current_depth in propagation.py --- monkey/infection_monkey/utils/propagation.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/monkey/infection_monkey/utils/propagation.py b/monkey/infection_monkey/utils/propagation.py index ed9567c26..004bafdd2 100644 --- a/monkey/infection_monkey/utils/propagation.py +++ b/monkey/infection_monkey/utils/propagation.py @@ -1,2 +1,2 @@ -def should_propagate(config: dict, depth: int) -> bool: - return config["config"]["depth"] > depth +def should_propagate(config: dict, current_depth: int) -> bool: + return config["config"]["depth"] > current_depth From 8d2078048cdfb381ed5c22dc56dd40003c19bdc2 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Wed, 22 Jun 2022 17:39:25 +0300 Subject: [PATCH 12/14] Agent: Change the positive_int definition to contain 0 --- monkey/common/utils/argparse_types.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monkey/common/utils/argparse_types.py b/monkey/common/utils/argparse_types.py index a920ef1b4..fd6f94c33 100644 --- a/monkey/common/utils/argparse_types.py +++ b/monkey/common/utils/argparse_types.py @@ -3,7 +3,7 @@ import argparse def positive_int(_input: str): int_value = int(_input) - if int_value <= 0: + if int_value < 0: raise argparse.ArgumentTypeError(f"{_input} is not a positive integer") return int_value From 1199c72f0d947822934a1352a79869bcb227ce41 Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Wed, 22 Jun 2022 10:44:02 -0400 Subject: [PATCH 13/14] Island: Modify skipping propagation log message --- monkey/infection_monkey/master/automated_master.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monkey/infection_monkey/master/automated_master.py b/monkey/infection_monkey/master/automated_master.py index 4d2cb3902..f79fd5f12 100644 --- a/monkey/infection_monkey/master/automated_master.py +++ b/monkey/infection_monkey/master/automated_master.py @@ -176,7 +176,7 @@ class AutomatedMaster(IMaster): if should_propagate(self._control_channel.get_config(), self._current_depth): self._propagator.propagate(config["propagation"], current_depth, self._stop) else: - logger.info("Skipping propagation, maximum depth reached") + logger.info("Skipping propagation: maximum depth reached") payload_thread = create_daemon_thread( target=self._run_plugins, From eeba0e0616a77e6a47c59c0282344effdf37511e Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Wed, 22 Jun 2022 10:59:46 -0400 Subject: [PATCH 14/14] UT: Add tests for should_propagate --- .../utils/test_propagation.py | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 monkey/tests/unit_tests/infection_monkey/utils/test_propagation.py diff --git a/monkey/tests/unit_tests/infection_monkey/utils/test_propagation.py b/monkey/tests/unit_tests/infection_monkey/utils/test_propagation.py new file mode 100644 index 000000000..37f7194a6 --- /dev/null +++ b/monkey/tests/unit_tests/infection_monkey/utils/test_propagation.py @@ -0,0 +1,32 @@ +from infection_monkey.utils.propagation import should_propagate + + +def get_config(max_depth): + return {"config": {"depth": max_depth}} + + +def test_should_propagate_current_less_than_max(): + max_depth = 2 + current_depth = 1 + + config = get_config(max_depth) + + assert should_propagate(config, current_depth) is True + + +def test_should_propagate_current_greater_than_max(): + max_depth = 2 + current_depth = 3 + + config = get_config(max_depth) + + assert should_propagate(config, current_depth) is False + + +def test_should_propagate_current_equal_to_max(): + max_depth = 2 + current_depth = max_depth + + config = get_config(max_depth) + + assert should_propagate(config, current_depth) is False