forked from p15670423/monkey
Agent: Create HTTP handler class dynamically for ExploitClassHTTPServer
This commit is contained in:
parent
896bcfebea
commit
3cd3d661bf
|
@ -7,38 +7,36 @@ logger = logging.getLogger(__name__)
|
||||||
HTTP_TOO_MANY_REQUESTS_ERROR_CODE = 429
|
HTTP_TOO_MANY_REQUESTS_ERROR_CODE = 429
|
||||||
|
|
||||||
|
|
||||||
# If we need to run multiple HTTP servers in parallel, we'll need to either:
|
def do_GET(self):
|
||||||
# 1. Use multiprocessing so that each HTTPHandler class has its own class_downloaded variable
|
with self.download_lock:
|
||||||
# 2. Create a metaclass and define the handler class dymanically at runtime
|
if self.class_downloaded.is_set():
|
||||||
class HTTPHandler(http.server.BaseHTTPRequestHandler):
|
self.send_error(
|
||||||
|
HTTP_TOO_MANY_REQUESTS_ERROR_CODE,
|
||||||
|
"Java exploit class has already been downloaded",
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
java_class: bytes
|
self.class_downloaded.set()
|
||||||
class_downloaded: threading.Event
|
|
||||||
download_lock: threading.Lock
|
|
||||||
|
|
||||||
@classmethod
|
logger.info("Java class server received a GET request!")
|
||||||
def initialize(cls, java_class: bytes, class_downloaded: threading.Event):
|
self.send_response(200)
|
||||||
cls.java_class = java_class
|
self.send_header("Content-type", "application/octet-stream")
|
||||||
cls.class_downloaded = class_downloaded
|
self.end_headers()
|
||||||
cls.download_lock = threading.Lock()
|
logger.info("Sending the payload class!")
|
||||||
|
self.wfile.write(self.java_class)
|
||||||
|
|
||||||
def do_GET(self):
|
|
||||||
with HTTPHandler.download_lock:
|
|
||||||
if HTTPHandler.class_downloaded.is_set():
|
|
||||||
self.send_error(
|
|
||||||
HTTP_TOO_MANY_REQUESTS_ERROR_CODE,
|
|
||||||
"Java exploit class has already been downloaded",
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
HTTPHandler.class_downloaded.set()
|
def get_new_http_handler_class(java_class: bytes, class_downloaded: threading.Event):
|
||||||
|
return type(
|
||||||
logger.info("Java class server received a GET request!")
|
"http_handler_class",
|
||||||
self.send_response(200)
|
(http.server.BaseHTTPRequestHandler,),
|
||||||
self.send_header("Content-type", "application/octet-stream")
|
{
|
||||||
self.end_headers()
|
"java_class": java_class,
|
||||||
logger.info("Sending the payload class!")
|
"class_downloaded": class_downloaded,
|
||||||
self.wfile.write(self.java_class)
|
"download_lock": threading.Lock(),
|
||||||
|
"do_GET": do_GET,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class ExploitClassHTTPServer:
|
class ExploitClassHTTPServer:
|
||||||
|
@ -62,9 +60,9 @@ class ExploitClassHTTPServer:
|
||||||
self._class_downloaded = threading.Event()
|
self._class_downloaded = threading.Event()
|
||||||
self._poll_interval = poll_interval
|
self._poll_interval = poll_interval
|
||||||
|
|
||||||
HTTPHandler.initialize(java_class, self._class_downloaded)
|
http_handler_class = get_new_http_handler_class(java_class, self._class_downloaded)
|
||||||
|
|
||||||
self._server = http.server.HTTPServer((ip, port), HTTPHandler)
|
self._server = http.server.HTTPServer((ip, port), http_handler_class)
|
||||||
# Setting `daemon=True` to save ourselves some trouble when this is merged to the
|
# Setting `daemon=True` to save ourselves some trouble when this is merged to the
|
||||||
# agent-refactor branch.
|
# agent-refactor branch.
|
||||||
# TODO: Make a call to `create_daemon_thread()` instead of calling the `Thread()`
|
# TODO: Make a call to `create_daemon_thread()` instead of calling the `Thread()`
|
||||||
|
|
Loading…
Reference in New Issue