
A scanner for the FortiNet vulnerability CVE-2025-64446
Simple Python helper to probe Fortinet/FortiWeb targets for the fwbcgi authentication bypass pattern reported by watchTowr Labs. Intelligence and request details came from: https://labs.watchtowr.com/when-the-impersonation-function-gets-used-to-impersonate-users-fortinet-fortiweb-auth-bypass/
python3 scanner.py http://192.168.9.1:80
python3 scanner.py -f targets.txt --find-forti --follow-redirects
Targets must include their scheme explicitly (http:// or https://). If the port is omitted, the scanner assumes 80 for HTTP or 443 for HTTPS. Outputs one line per target with [+] VULNERABLE, [+] MAY BE VULNERABLE, [+] PATCHED, [+] POSSIBLY PATCHED, or [-] INDETERMINATE; optionally highlights words containing “forti”.
targets: one or more <scheme>://<host>[:<port>] entries on the command line (ports default to 80 for HTTP or 443 for HTTPS).-f/--targets-file: read additional targets from file(s); same <scheme>://<host>[:<port>] format.--timeout: socket timeout in seconds (default 5).--find-forti: print unique tokens containing “forti” that appeared in the response body.--follow-redirects: opt-in redirect handling for targets that issue 30x responses.--max-redirects: limit for redirect hops when --follow-redirects is active (default 3, disables following even if the flag is present).Due to a lack of decent testing infra, here's the naive test suite I used.
PYTHONPYCACHEPREFIX=./.pycache python3 -m unittest discover -s tests
The scanner relies on TLS 1.2+ support to talk to modern Fortinet or Cloudflare-fronted sites. Make sure the python3 you run is linked against a recent OpenSSL build:
/usr/bin/python3) is tied to LibreSSL 2.8 and cannot negotiate TLS 1.3, causing TLSV1_ALERT_PROTOCOL_VERSION errors. Install a modern interpreter via Homebrew (brew install python) or pyenv and run the scanner with that binary (e.g., /opt/homebrew/bin/python3).python3 - <<'PY'\nimport ssl; print(ssl.OPENSSL_VERSION)\nPY. If it reports something older, install an updated python (pyenv, distro backports, etc.).ssl.OPENSSL_VERSION snippet if you’re running inside WSL or an older virtual environment.If you must run on an older interpreter, expect HTTPS targets that require TLS 1.3 to fail; HTTP targets continue to work regardless.
0--validate-tls: force certificate validation for HTTPS targets and redirects (default behavior skips validation to avoid blocking on self-signed certs).--workers: number of concurrent scans to run via asyncio (default 10).--user-agent: custom HTTP User-Agent header (default fwbcgi-scanner/1.0).--csv-output: write <target>,<classification> rows to the given CSV file in addition to console output.