From db58b0b27d38c87af561d5b3947d73cafec0cc66 Mon Sep 17 00:00:00 2001 From: Shreya Malviya Date: Fri, 3 Dec 2021 17:39:37 +0530 Subject: [PATCH 1/4] Agent, UT: Remove --vulnerable-port CLI argument --- monkey/infection_monkey/dropper.py | 1 - monkey/infection_monkey/exploit/hadoop.py | 4 +--- monkey/infection_monkey/exploit/mssqlexec.py | 4 +--- monkey/infection_monkey/exploit/powershell.py | 1 - monkey/infection_monkey/exploit/shellshock.py | 1 - monkey/infection_monkey/exploit/smbexec.py | 15 +-------------- monkey/infection_monkey/exploit/sshexec.py | 4 +--- .../infection_monkey/exploit/tools/http_tools.py | 4 ---- monkey/infection_monkey/exploit/web_rce.py | 10 ++-------- monkey/infection_monkey/exploit/win_ms08_067.py | 5 +---- monkey/infection_monkey/exploit/wmiexec.py | 6 +----- monkey/infection_monkey/exploit/zerologon.py | 1 - monkey/infection_monkey/monkey.py | 1 - monkey/infection_monkey/utils/commands.py | 9 +-------- .../infection_monkey/utils/test_commands.py | 10 +++------- 15 files changed, 12 insertions(+), 64 deletions(-) diff --git a/monkey/infection_monkey/dropper.py b/monkey/infection_monkey/dropper.py index e2f59e601..3a153bf44 100644 --- a/monkey/infection_monkey/dropper.py +++ b/monkey/infection_monkey/dropper.py @@ -139,7 +139,6 @@ class MonkeyDrops(object): server=self.opts.server, depth=self.opts.depth, location=None, - vulnerable_port=self.opts.vulnerable_port, ) if OperatingSystem.Windows == SystemInfoCollector.get_os(): diff --git a/monkey/infection_monkey/exploit/hadoop.py b/monkey/infection_monkey/exploit/hadoop.py index f221ebe1f..53a98bd5a 100644 --- a/monkey/infection_monkey/exploit/hadoop.py +++ b/monkey/infection_monkey/exploit/hadoop.py @@ -87,9 +87,7 @@ class HadoopExploiter(WebRCE): def build_command(self, path, http_path): # Build command to execute - monkey_cmd = build_monkey_commandline( - self.host, get_monkey_depth() - 1, vulnerable_port=HadoopExploiter.HADOOP_PORTS[0][0] - ) + monkey_cmd = build_monkey_commandline(self.host, get_monkey_depth() - 1) if "linux" in self.host.os["type"]: base_command = HADOOP_LINUX_COMMAND else: diff --git a/monkey/infection_monkey/exploit/mssqlexec.py b/monkey/infection_monkey/exploit/mssqlexec.py index ef88d6cf2..a3b6d8191 100644 --- a/monkey/infection_monkey/exploit/mssqlexec.py +++ b/monkey/infection_monkey/exploit/mssqlexec.py @@ -147,9 +147,7 @@ class MSSQLExploiter(HostExploiter): def get_monkey_launch_command(self): dst_path = get_monkey_dest_path(self.monkey_server.http_path) # Form monkey's launch command - monkey_args = build_monkey_commandline( - self.host, get_monkey_depth() - 1, MSSQLExploiter.SQL_DEFAULT_TCP_PORT, dst_path - ) + monkey_args = build_monkey_commandline(self.host, get_monkey_depth() - 1, dst_path) suffix = ">>{}".format(self.payload_file_path) prefix = MSSQLExploiter.EXPLOIT_COMMAND_PREFIX return MSSQLLimitedSizePayload( diff --git a/monkey/infection_monkey/exploit/powershell.py b/monkey/infection_monkey/exploit/powershell.py index f2883bb63..6db20b6a4 100644 --- a/monkey/infection_monkey/exploit/powershell.py +++ b/monkey/infection_monkey/exploit/powershell.py @@ -208,7 +208,6 @@ def build_monkey_execution_command(host: VictimHost, depth: int, executable_path monkey_params = build_monkey_commandline( target_host=host, depth=depth, - vulnerable_port=None, location=executable_path, ) diff --git a/monkey/infection_monkey/exploit/shellshock.py b/monkey/infection_monkey/exploit/shellshock.py index efe0c10cc..2f1284201 100644 --- a/monkey/infection_monkey/exploit/shellshock.py +++ b/monkey/infection_monkey/exploit/shellshock.py @@ -164,7 +164,6 @@ class ShellShockExploiter(HostExploiter): cmdline += build_monkey_commandline( self.host, get_monkey_depth() - 1, - HTTPTools.get_port_from_url(url), dropper_target_path_linux, ) cmdline += " & " diff --git a/monkey/infection_monkey/exploit/smbexec.py b/monkey/infection_monkey/exploit/smbexec.py index 8dfe8ed75..4dac63cd9 100644 --- a/monkey/infection_monkey/exploit/smbexec.py +++ b/monkey/infection_monkey/exploit/smbexec.py @@ -28,7 +28,6 @@ class SmbExploiter(HostExploiter): def __init__(self, host): super(SmbExploiter, self).__init__(host) - self.vulnerable_port = None def is_os_supported(self): if super(SmbExploiter, self).is_os_supported(): @@ -112,7 +111,6 @@ class SmbExploiter(HostExploiter): logger.debug("Exploiter SmbExec is giving up...") return False - self.set_vulnerable_port() # execute the remote dropper in case the path isn't final if remote_full_path.lower() != self._config.dropper_target_path_win_32.lower(): cmdline = DROPPER_CMDLINE_DETACHED_WINDOWS % { @@ -120,15 +118,12 @@ class SmbExploiter(HostExploiter): } + build_monkey_commandline( self.host, get_monkey_depth() - 1, - self.vulnerable_port, self._config.dropper_target_path_win_32, ) else: cmdline = MONKEY_CMDLINE_DETACHED_WINDOWS % { "monkey_path": remote_full_path - } + build_monkey_commandline( - self.host, get_monkey_depth() - 1, vulnerable_port=self.vulnerable_port - ) + } + build_monkey_commandline(self.host, get_monkey_depth() - 1) smb_conn = False for str_bind_format, port in SmbExploiter.KNOWN_PROTOCOLS.values(): @@ -198,11 +193,3 @@ class SmbExploiter(HostExploiter): ) ) return True - - def set_vulnerable_port(self): - if "tcp-445" in self.host.services: - self.vulnerable_port = "445" - elif "tcp-139" in self.host.services: - self.vulnerable_port = "139" - else: - self.vulnerable_port = None diff --git a/monkey/infection_monkey/exploit/sshexec.py b/monkey/infection_monkey/exploit/sshexec.py index be59b0ca6..0af7f7174 100644 --- a/monkey/infection_monkey/exploit/sshexec.py +++ b/monkey/infection_monkey/exploit/sshexec.py @@ -197,9 +197,7 @@ class SSHExploiter(HostExploiter): try: cmdline = "%s %s" % (self._config.dropper_target_path_linux, MONKEY_ARG) - cmdline += build_monkey_commandline( - self.host, get_monkey_depth() - 1, vulnerable_port=SSH_PORT - ) + cmdline += build_monkey_commandline(self.host, get_monkey_depth() - 1) cmdline += " > /dev/null 2>&1 &" ssh.exec_command(cmdline) diff --git a/monkey/infection_monkey/exploit/tools/http_tools.py b/monkey/infection_monkey/exploit/tools/http_tools.py index 9ef73090b..25aca3321 100644 --- a/monkey/infection_monkey/exploit/tools/http_tools.py +++ b/monkey/infection_monkey/exploit/tools/http_tools.py @@ -80,10 +80,6 @@ class HTTPTools(object): httpd, ) - @staticmethod - def get_port_from_url(url: str) -> int: - return urllib.parse.urlparse(url).port - class MonkeyHTTPServer(HTTPTools): def __init__(self, host): diff --git a/monkey/infection_monkey/exploit/web_rce.py b/monkey/infection_monkey/exploit/web_rce.py index a8ce60a40..48fd19573 100644 --- a/monkey/infection_monkey/exploit/web_rce.py +++ b/monkey/infection_monkey/exploit/web_rce.py @@ -53,7 +53,6 @@ class WebRCE(HostExploiter): self.skip_exist = self._config.skip_exploit_if_file_exist self.vulnerable_urls = [] self.target_url = None - self.vulnerable_port = None def get_exploit_config(self): """ @@ -106,7 +105,6 @@ class WebRCE(HostExploiter): return False self.target_url = self.get_target_url() - self.vulnerable_port = HTTPTools.get_port_from_url(self.target_url) # Skip if monkey already exists and this option is given if ( @@ -455,18 +453,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, get_monkey_depth() - 1, self.vulnerable_port, default_path - ) + monkey_cmd = build_monkey_commandline(self.host, get_monkey_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, get_monkey_depth() - 1, self.vulnerable_port - ) + monkey_cmd = build_monkey_commandline(self.host, get_monkey_depth() - 1) command = RUN_MONKEY % { "monkey_path": path, "monkey_type": MONKEY_ARG, diff --git a/monkey/infection_monkey/exploit/win_ms08_067.py b/monkey/infection_monkey/exploit/win_ms08_067.py index cff31e083..db6df1212 100644 --- a/monkey/infection_monkey/exploit/win_ms08_067.py +++ b/monkey/infection_monkey/exploit/win_ms08_067.py @@ -289,15 +289,12 @@ class Ms08_067_Exploiter(HostExploiter): } + build_monkey_commandline( self.host, get_monkey_depth() - 1, - SRVSVC_Exploit.TELNET_PORT, self._config.dropper_target_path_win_32, ) else: cmdline = MONKEY_CMDLINE_WINDOWS % { "monkey_path": remote_full_path - } + build_monkey_commandline( - self.host, get_monkey_depth() - 1, vulnerable_port=SRVSVC_Exploit.TELNET_PORT - ) + } + build_monkey_commandline(self.host, get_monkey_depth() - 1) try: sock.send(("start %s\r\n" % (cmdline,)).encode()) diff --git a/monkey/infection_monkey/exploit/wmiexec.py b/monkey/infection_monkey/exploit/wmiexec.py index 5af6606c4..54095d1e7 100644 --- a/monkey/infection_monkey/exploit/wmiexec.py +++ b/monkey/infection_monkey/exploit/wmiexec.py @@ -20,7 +20,6 @@ class WmiExploiter(HostExploiter): _TARGET_OS_TYPE = ["windows"] EXPLOIT_TYPE = ExploitType.BRUTE_FORCE _EXPLOITED_SERVICE = "WMI (Windows Management Instrumentation)" - VULNERABLE_PORT = 135 def __init__(self, host): super(WmiExploiter, self).__init__(host) @@ -113,15 +112,12 @@ class WmiExploiter(HostExploiter): } + build_monkey_commandline( self.host, get_monkey_depth() - 1, - WmiExploiter.VULNERABLE_PORT, self._config.dropper_target_path_win_32, ) else: cmdline = MONKEY_CMDLINE_WINDOWS % { "monkey_path": remote_full_path - } + build_monkey_commandline( - self.host, get_monkey_depth() - 1, WmiExploiter.VULNERABLE_PORT - ) + } + build_monkey_commandline(self.host, get_monkey_depth() - 1) # execute the remote monkey result = WmiTools.get_object(wmi_connection, "Win32_Process").Create( diff --git a/monkey/infection_monkey/exploit/zerologon.py b/monkey/infection_monkey/exploit/zerologon.py index a43639614..a882b17de 100644 --- a/monkey/infection_monkey/exploit/zerologon.py +++ b/monkey/infection_monkey/exploit/zerologon.py @@ -36,7 +36,6 @@ class ZerologonExploiter(HostExploiter): def __init__(self, host: object): super().__init__(host) - self.vulnerable_port = None self.exploit_info["credentials"] = {} self.exploit_info["password_restored"] = None self._extracted_creds = {} diff --git a/monkey/infection_monkey/monkey.py b/monkey/infection_monkey/monkey.py index 4eb959129..7236af3fd 100644 --- a/monkey/infection_monkey/monkey.py +++ b/monkey/infection_monkey/monkey.py @@ -50,7 +50,6 @@ class InfectionMonkey: arg_parser.add_argument("-t", "--tunnel") arg_parser.add_argument("-s", "--server") arg_parser.add_argument("-d", "--depth", type=int) - arg_parser.add_argument("-vp", "--vulnerable-port") opts, _ = arg_parser.parse_known_args(args) InfectionMonkey._log_arguments(opts) return opts diff --git a/monkey/infection_monkey/utils/commands.py b/monkey/infection_monkey/utils/commands.py index ee2f0153a..284729206 100644 --- a/monkey/infection_monkey/utils/commands.py +++ b/monkey/infection_monkey/utils/commands.py @@ -3,9 +3,7 @@ from infection_monkey.model import CMD_CARRY_OUT, CMD_EXE, MONKEY_ARG from infection_monkey.model.host import VictimHost -def build_monkey_commandline( - target_host: VictimHost, depth: int, vulnerable_port: str, location: str = None -) -> str: +def build_monkey_commandline(target_host: VictimHost, depth: int, location: str = None) -> str: return " " + " ".join( build_monkey_commandline_explicitly( @@ -14,7 +12,6 @@ def build_monkey_commandline( target_host.default_server, depth, location, - vulnerable_port, ) ) @@ -25,7 +22,6 @@ def build_monkey_commandline_explicitly( server: str = None, depth: int = None, location: str = None, - vulnerable_port: str = None, ) -> list: cmdline = [] @@ -46,9 +42,6 @@ def build_monkey_commandline_explicitly( if location is not None: cmdline.append("-l") cmdline.append(str(location)) - if vulnerable_port is not None: - cmdline.append("-vp") - cmdline.append(str(vulnerable_port)) return cmdline 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 a3f210533..5d33cb8ae 100644 --- a/monkey/tests/unit_tests/infection_monkey/utils/test_commands.py +++ b/monkey/tests/unit_tests/infection_monkey/utils/test_commands.py @@ -20,11 +20,9 @@ def test_build_monkey_commandline_explicitly_arguments(): "0", "-l", "C:\\windows\\abc", - "-vp", - "80", ] actual = build_monkey_commandline_explicitly( - "101010", "10.10.101.10", "127.127.127.127:5000", 0, "C:\\windows\\abc", "80" + "101010", "10.10.101.10", "127.127.127.127:5000", 0, "C:\\windows\\abc" ) assert expected == actual @@ -100,9 +98,7 @@ def test_build_monkey_commandline(): example_host = VictimHost(ip_addr="bla") example_host.set_default_server("101010") - expected = f" -p {GUID} -s 101010 -d 0 -l /home/bla -vp 80" - actual = build_monkey_commandline( - target_host=example_host, depth=0, vulnerable_port="80", location="/home/bla" - ) + expected = f" -p {GUID} -s 101010 -d 0 -l /home/bla" + actual = build_monkey_commandline(target_host=example_host, depth=0, location="/home/bla") assert expected == actual From 32c2d744b5a3f7784f2a22c9555495221660b70c Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Tue, 7 Dec 2021 13:21:44 -0500 Subject: [PATCH 2/4] Agent: Remove should_monkey_run() performance check --- monkey/infection_monkey/control.py | 12 ------------ monkey/infection_monkey/monkey.py | 20 -------------------- 2 files changed, 32 deletions(-) diff --git a/monkey/infection_monkey/control.py b/monkey/infection_monkey/control.py index 88a8e43fa..9d89854cc 100644 --- a/monkey/infection_monkey/control.py +++ b/monkey/infection_monkey/control.py @@ -407,18 +407,6 @@ class ControlClient(object): except requests.exceptions.RequestException: return False - @staticmethod - def should_monkey_run(vulnerable_port: str) -> bool: - if ( - vulnerable_port - and WormConfiguration.get_hop_distance_to_island() > 1 - and ControlClient.can_island_see_port(vulnerable_port) - and WormConfiguration.started_on_island - ): - return False - - return True - @staticmethod def can_island_see_port(port): try: diff --git a/monkey/infection_monkey/monkey.py b/monkey/infection_monkey/monkey.py index 7236af3fd..e63484e70 100644 --- a/monkey/infection_monkey/monkey.py +++ b/monkey/infection_monkey/monkey.py @@ -13,7 +13,6 @@ from infection_monkey.control import ControlClient from infection_monkey.master.mock_master import MockMaster from infection_monkey.model import DELAY_DELETE_CMD from infection_monkey.network.firewall import app as firewall -from infection_monkey.network.tools import is_running_on_island from infection_monkey.puppet.mock_puppet import MockPuppet from infection_monkey.system_singleton import SystemSingleton from infection_monkey.telemetry.attack.t1106_telem import T1106Telem @@ -144,13 +143,6 @@ class InfectionMonkey: def _setup(self): logger.debug("Starting the setup phase.") - if self._should_exit_for_performance(): - logger.info( - "Monkey shouldn't run on current machine to improve perfomance" - "(it will be exploited later with more depth)." - ) - return - if firewall.is_enabled(): firewall.add_firewall_rule() @@ -163,18 +155,6 @@ class InfectionMonkey: register_signal_handlers(self._master) - def _should_exit_for_performance(self): - """ - This method implements propagation performance enhancing algorithm that - kicks in if the run was started from the Island. - Should get replaced by other, better performance enhancement solutions - """ - if is_running_on_island(): - WormConfiguration.started_on_island = True - ControlClient.report_start_on_island() - - return not ControlClient.should_monkey_run(self._opts.vulnerable_port) - def _is_another_monkey_running(self): return not self._singleton.try_lock() From 476b6c3b36a9c83c9bd3a6bafee739fbe0a8d4dd Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Tue, 7 Dec 2021 13:24:58 -0500 Subject: [PATCH 3/4] Agent: Remove can_island_see_port() --- monkey/infection_monkey/control.py | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/monkey/infection_monkey/control.py b/monkey/infection_monkey/control.py index 9d89854cc..878945433 100644 --- a/monkey/infection_monkey/control.py +++ b/monkey/infection_monkey/control.py @@ -13,11 +13,7 @@ import infection_monkey.monkeyfs as monkeyfs import infection_monkey.tunnel as tunnel from common.common_consts.api_url_consts import T1216_PBA_FILE_DOWNLOAD_PATH from common.common_consts.time_formats import DEFAULT_TIME_FORMAT -from common.common_consts.timeouts import ( - LONG_REQUEST_TIMEOUT, - MEDIUM_REQUEST_TIMEOUT, - SHORT_REQUEST_TIMEOUT, -) +from common.common_consts.timeouts import LONG_REQUEST_TIMEOUT, MEDIUM_REQUEST_TIMEOUT from infection_monkey.config import GUID, WormConfiguration from infection_monkey.network.info import local_ips from infection_monkey.transport.http import HTTPConnectProxy @@ -407,21 +403,6 @@ class ControlClient(object): except requests.exceptions.RequestException: return False - @staticmethod - def can_island_see_port(port): - try: - url = ( - f"https://{WormConfiguration.current_server}/api/monkey_control" - f"/check_remote_port/{port}" - ) - response = requests.get( # noqa: DUO123 - url, verify=False, timeout=SHORT_REQUEST_TIMEOUT - ) - response = json.loads(response.content.decode()) - return response["status"] == "port_visible" - except requests.exceptions.RequestException: - return False - @staticmethod def report_start_on_island(): requests.post( # noqa: DUO123 From 5052e21d97e21d0393af2f6eaf78db1d2efdadde Mon Sep 17 00:00:00 2001 From: Mike Salvatore Date: Tue, 7 Dec 2021 13:25:16 -0500 Subject: [PATCH 4/4] Island: Remove /api/monkey_control/check_remote_port/ --- CHANGELOG.md | 1 + monkey/monkey_island/cc/app.py | 2 -- .../resources/monkey_control/remote_port_check.py | 14 -------------- 3 files changed, 1 insertion(+), 16 deletions(-) delete mode 100644 monkey/monkey_island/cc/resources/monkey_control/remote_port_check.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f5a59bb8..3af52e3b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,7 @@ Changelog](https://keepachangelog.com/en/1.0.0/). - Max iterations and timeout between iterations config options. #1600 - MITRE ATT&CK configuration screen. #1532 - Propagation credentials from "GET /api/monkey/" endpoint. #1538 +- "GET /api/monkey_control/check_remote_port/" endpoint. #1635 ### Fixed - A bug in network map page that caused delay of telemetry log loading. #1545 diff --git a/monkey/monkey_island/cc/app.py b/monkey/monkey_island/cc/app.py index 376d0221b..5bb4b80bc 100644 --- a/monkey/monkey_island/cc/app.py +++ b/monkey/monkey_island/cc/app.py @@ -30,7 +30,6 @@ from monkey_island.cc.resources.island_mode import IslandMode from monkey_island.cc.resources.local_run import LocalRun from monkey_island.cc.resources.log import Log from monkey_island.cc.resources.monkey import Monkey -from monkey_island.cc.resources.monkey_control.remote_port_check import RemotePortCheck from monkey_island.cc.resources.monkey_control.started_on_island import StartedOnIsland from monkey_island.cc.resources.monkey_control.stop_agent_check import StopAgentCheck from monkey_island.cc.resources.monkey_download import MonkeyDownload @@ -173,7 +172,6 @@ def init_api_resources(api): api.add_resource(PropagationCredentials, "/api/propagationCredentials") api.add_resource(RemoteRun, "/api/remote-monkey", "/api/remote-monkey/") api.add_resource(VersionUpdate, "/api/version-update", "/api/version-update/") - api.add_resource(RemotePortCheck, "/api/monkey_control/check_remote_port/") api.add_resource(StartedOnIsland, "/api/monkey_control/started_on_island") api.add_resource(StopAgentCheck, "/api/monkey_control/") api.add_resource(ScoutSuiteAuth, "/api/scoutsuite_auth/") diff --git a/monkey/monkey_island/cc/resources/monkey_control/remote_port_check.py b/monkey/monkey_island/cc/resources/monkey_control/remote_port_check.py deleted file mode 100644 index 06e49b145..000000000 --- a/monkey/monkey_island/cc/resources/monkey_control/remote_port_check.py +++ /dev/null @@ -1,14 +0,0 @@ -import flask_restful -from flask import request - -from monkey_island.cc.services.remote_port_check import check_tcp_port - - -class RemotePortCheck(flask_restful.Resource): - - # Used by monkey. can't secure. - def get(self, port): - if port and check_tcp_port(request.remote_addr, port): - return {"status": "port_visible"} - else: - return {"status": "port_invisible"}