From 6073e9f677c2d27df62841d5804c249f33764063 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Thu, 24 Jan 2019 17:28:44 +0200 Subject: [PATCH 1/5] Improved the speed of weblogic exploiter --- monkey/infection_monkey/exploit/weblogic.py | 36 ++++++++++++++++++--- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/monkey/infection_monkey/exploit/weblogic.py b/monkey/infection_monkey/exploit/weblogic.py index ac78555af..98b20ad6c 100644 --- a/monkey/infection_monkey/exploit/weblogic.py +++ b/monkey/infection_monkey/exploit/weblogic.py @@ -13,13 +13,16 @@ from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer import threading import logging +import time __author__ = "VakarisZ" LOG = logging.getLogger(__name__) # How long server waits for get request in seconds SERVER_TIMEOUT = 4 -# How long to wait for a request to go to vuln machine and then to our server from there. In seconds +# How long should be wait after each request in seconds +REQUEST_DELAY = 0.0001 +# How long to wait for a sign(request from host) that server is vulnerable. In seconds REQUEST_TIMEOUT = 2 # How long to wait for response in exploitation. In seconds EXECUTION_TIMEOUT = 15 @@ -66,18 +69,41 @@ class WebLogicExploiter(WebRCE): print(e) return True - def check_if_exploitable(self, url): + def add_vulnerable_urls(self, urls): + """ + Overrides parent method to use listener server + """ # Server might get response faster than it starts listening to it, we need a lock httpd, lock = self._start_http_server() + exploitable = False + + for url in urls: + if self.check_if_exploitable(url, httpd): + exploitable = True + break + + if not exploitable and httpd.get_requests < 1: + # Wait for responses + time.sleep(REQUEST_TIMEOUT) + + if httpd.get_requests > 0: + # Add all urls because we don't know which one is vulnerable + self.vulnerable_urls.extend(urls) + self._exploit_info['vulnerable_urls'] = self.vulnerable_urls + else: + LOG.info("No vulnerable urls found, skipping.") + + self._stop_http_server(httpd, lock) + + def check_if_exploitable(self, url, httpd): payload = self.get_test_payload(ip=httpd._local_ip, port=httpd._local_port) try: - post(url, data=payload, headers=HEADERS, timeout=REQUEST_TIMEOUT, verify=False) + post(url, data=payload, headers=HEADERS, timeout=REQUEST_DELAY, verify=False) except exceptions.ReadTimeout: - # Our request does not get response thus we get ReadTimeout error + # Our request will not get response thus we get ReadTimeout error pass except Exception as e: LOG.error("Something went wrong: %s" % e) - self._stop_http_server(httpd, lock) return httpd.get_requests > 0 def _start_http_server(self): From e0a98664f64d9a6e77a04f55a7f0971cdc431360 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Tue, 29 Jan 2019 10:17:25 +0200 Subject: [PATCH 2/5] Fixes the config import on MSSQL exploiter --- monkey/infection_monkey/exploit/mssqlexec.py | 1 - 1 file changed, 1 deletion(-) diff --git a/monkey/infection_monkey/exploit/mssqlexec.py b/monkey/infection_monkey/exploit/mssqlexec.py index 985394a29..128755de0 100644 --- a/monkey/infection_monkey/exploit/mssqlexec.py +++ b/monkey/infection_monkey/exploit/mssqlexec.py @@ -21,7 +21,6 @@ class MSSQLExploiter(HostExploiter): def __init__(self, host): super(MSSQLExploiter, self).__init__(host) - self._config = __import__('config').WormConfiguration self.attacks_list = [mssqlexec_utils.CmdShellAttack] def create_payload_file(self, payload_path=DEFAULT_PAYLOAD_PATH): From 11c0d7773e7b57a7345d89a6142ec7c00416b366 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Tue, 29 Jan 2019 11:51:42 +0200 Subject: [PATCH 3/5] Fixed telemetry expecting a 'scanner' field --- .../monkey_island/cc/resources/telemetry.py | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/monkey/monkey_island/cc/resources/telemetry.py b/monkey/monkey_island/cc/resources/telemetry.py index be363ce33..57148aa0f 100644 --- a/monkey/monkey_island/cc/resources/telemetry.py +++ b/monkey/monkey_island/cc/resources/telemetry.py @@ -149,8 +149,7 @@ class Telemetry(flask_restful.Resource): new_scan = \ { "timestamp": telemetry_json["timestamp"], - "data": data, - "scanner": telemetry_json['data']['scanner'] + "data": data } mongo.db.edge.update( {"_id": edge["_id"]}, @@ -160,16 +159,15 @@ class Telemetry(flask_restful.Resource): node = mongo.db.node.find_one({"_id": edge["to"]}) if node is not None: - if new_scan["scanner"] == "TcpScanner": - scan_os = new_scan["data"]["os"] - if "type" in scan_os: - mongo.db.node.update({"_id": node["_id"]}, - {"$set": {"os.type": scan_os["type"]}}, - upsert=False) - if "version" in scan_os: - mongo.db.node.update({"_id": node["_id"]}, - {"$set": {"os.version": scan_os["version"]}}, - upsert=False) + scan_os = new_scan["data"]["os"] + if "type" in scan_os: + mongo.db.node.update({"_id": node["_id"]}, + {"$set": {"os.type": scan_os["type"]}}, + upsert=False) + if "version" in scan_os: + mongo.db.node.update({"_id": node["_id"]}, + {"$set": {"os.version": scan_os["version"]}}, + upsert=False) @staticmethod def process_system_info_telemetry(telemetry_json): From 7ab22bb3e99bdeeb6a2ec4c8043f74cc0707a5a1 Mon Sep 17 00:00:00 2001 From: VakarisZ Date: Tue, 29 Jan 2019 13:09:38 +0200 Subject: [PATCH 4/5] Syntactic, small changes to weblogic and web_rce --- monkey/infection_monkey/exploit/web_rce.py | 2 +- monkey/infection_monkey/exploit/weblogic.py | 17 +++++++++-------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/monkey/infection_monkey/exploit/web_rce.py b/monkey/infection_monkey/exploit/web_rce.py index 6bc5fee37..d797f3a95 100644 --- a/monkey/infection_monkey/exploit/web_rce.py +++ b/monkey/infection_monkey/exploit/web_rce.py @@ -54,7 +54,7 @@ class WebRCE(HostExploiter): exploit_config['upload_commands'] = None # url_extensions: What subdirectories to scan (www.domain.com[/extension]). Eg. ["home", "index.php"] - exploit_config['url_extensions'] = None + exploit_config['url_extensions'] = [] # stop_checking_urls: If true it will stop checking vulnerable urls once one was found vulnerable. exploit_config['stop_checking_urls'] = False diff --git a/monkey/infection_monkey/exploit/weblogic.py b/monkey/infection_monkey/exploit/weblogic.py index 98b20ad6c..7cd1045f9 100644 --- a/monkey/infection_monkey/exploit/weblogic.py +++ b/monkey/infection_monkey/exploit/weblogic.py @@ -69,7 +69,7 @@ class WebLogicExploiter(WebRCE): print(e) return True - def add_vulnerable_urls(self, urls): + def add_vulnerable_urls(self, urls, stop_checking=False): """ Overrides parent method to use listener server """ @@ -78,7 +78,7 @@ class WebLogicExploiter(WebRCE): exploitable = False for url in urls: - if self.check_if_exploitable(url, httpd): + if self.check_if_exploitable_weblogic(url, httpd): exploitable = True break @@ -95,8 +95,8 @@ class WebLogicExploiter(WebRCE): self._stop_http_server(httpd, lock) - def check_if_exploitable(self, url, httpd): - payload = self.get_test_payload(ip=httpd._local_ip, port=httpd._local_port) + def check_if_exploitable_weblogic(self, url, httpd): + payload = self.get_test_payload(ip=httpd.local_ip, port=httpd.local_port) try: post(url, data=payload, headers=HEADERS, timeout=REQUEST_DELAY, verify=False) except exceptions.ReadTimeout: @@ -120,7 +120,8 @@ class WebLogicExploiter(WebRCE): lock.acquire() return httpd, lock - def _stop_http_server(self, httpd, lock): + @staticmethod + def _stop_http_server(httpd, lock): lock.release() httpd.join(SERVER_TIMEOUT) httpd.stop() @@ -194,8 +195,8 @@ class WebLogicExploiter(WebRCE): we determine if we can exploit by either getting a GET request from host or not. """ def __init__(self, local_ip, local_port, lock, max_requests=1): - self._local_ip = local_ip - self._local_port = local_port + self.local_ip = local_ip + self.local_port = local_port self.get_requests = 0 self.max_requests = max_requests self._stopped = False @@ -210,7 +211,7 @@ class WebLogicExploiter(WebRCE): LOG.info('Server received a request from vulnerable machine') self.get_requests += 1 LOG.info('Server waiting for exploited machine request...') - httpd = HTTPServer((self._local_ip, self._local_port), S) + httpd = HTTPServer((self.local_ip, self.local_port), S) httpd.daemon = True self.lock.release() while not self._stopped and self.get_requests < self.max_requests: From d2185d678308a7ff2e8811076c132114bb765c31 Mon Sep 17 00:00:00 2001 From: VakarisZ <36815064+VakarisZ@users.noreply.github.com> Date: Tue, 29 Jan 2019 17:56:37 +0200 Subject: [PATCH 5/5] Update readme.txt --- monkey/infection_monkey/readme.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/monkey/infection_monkey/readme.txt b/monkey/infection_monkey/readme.txt index 66ba14992..eb757d144 100644 --- a/monkey/infection_monkey/readme.txt +++ b/monkey/infection_monkey/readme.txt @@ -1,5 +1,5 @@ To get development versions of Monkey Island and Monkey look into deployment scripts folder. -If you only want to monkey from scratch you may refer to the instructions below. +If you only want to build monkey from scratch you may reference instructions below. The monkey is composed of three separate parts. * The Infection Monkey itself - PyInstaller compressed python archives @@ -76,4 +76,4 @@ Alternatively, if you build Mimikatz, put each version in a zip file. 1. The zip should contain only the Mimikatz DLL named tmpzipfile123456.dll 2. It should be protected using the password 'VTQpsJPXgZuXhX6x3V84G'. 3. The zip file should be named mk32.zip/mk64.zip accordingly. -4. Zipping with 7zip has been tested. Other zipping software may not work. \ No newline at end of file +4. Zipping with 7zip has been tested. Other zipping software may not work.