SeriesN-dayCVE-2024-21762CriticalPublic

The SSL-VPN pot of gold · Phase 3

Hunting the kit

Distinctive URIs, patch cuts, and what to do if the portal was reachable. The kit is on GitHub. This page is how you hunt it.

Name
Hunting the kit
Series
The SSL-VPN pot of gold
Phase
3 · Hunting the kit
Type
N-day analysis
CVE
CVE-2024-21762
CVE Risk
critical
Disclosure Status
public
Vendor
Fortinet
Affected
Internet-facing FortiGate SSL-VPN portals
Published
31 Aug 2026
Updated
01 Sept 2026
Tags
n-day, fortinet, ssl-vpn, detection, kev

HTTP that is not a login

Hunt these on the portal VIP, the WAF, the packet capture you swore you were keeping. Source IPs that never completed a legitimate VPN login but issued the following are doing something else with their afternoon.

  1. POST /aaaa/bbbb - Family A. Near-zero false-positive rate on FortiOS. See Phase 1.
  2. Transfer-Encoding: chunked toward the SSL-VPN portal, especially with abnormal chunk-size lines.
  3. Burst POST /remote/error with large, repetitive bodies.
  4. GET /remote/info then POST /remote/hostcheck_validate with enc=. Family B. Lexfo's XORtigate is the public map of that endpoint.
  5. Portal recon from poc.py: GET /remote/login and /sslvpn/js/login.js?q= (hash lookup, not a login).
  6. Outbound HTTP GET /s.js from the firewall to a host that is not yours. That file is now public: s.js.
  7. Outbound TCP from the firewall to 7777 / 8888 / 9999 (callback, shellcode pump, config receiver in this copy).
  8. TFTP from a 6.0 D-series box to anywhere. No.

On the device: sslvpnd crash/restart clustered with those URIs. Absence of crashes does not prove absence of hits. Public authors note a successful run can avoid a noisy crash. Assetnote and Bishop Fox both spent time on how this parser fails when you are not trying to be quiet.

Operator-box leftovers (if you are looking at a disk, not a firewall)
  • exp_<SKU>-v<ver>.py under an exp/ directory
  • poc.py, s.js, send_cmd.py
  • shellcode/ with shellcode_arm / shellcode_amd64 blobs
  • Possible salt-named JSON seed caches next to Family B scripts
  • pwntools / Python 3 / pocsuite3
  • Listeners on 7777, 8888, 9999

If you find that directory, you found the same class of gold I did. Do not run the clients against production. Preserve them. The copy I released is on GitHub.

Patch cuts (verify live text)

Advisories move. Confirm against Fortinet before you brief a VP.

CVE-2024-21762 / FG-IR-24-015 (Family A): FortiOS 7.4.0-7.4.2, 7.2.0-7.2.6, 7.0.0-7.0.13, 6.4.0-6.4.14, 6.2.0-6.2.15, 6.0.0-6.0.17. Fixes start at 7.4.3, 7.2.7, 7.0.14, 6.4.15, 6.2.16; 6.0 must migrate. Workaround in the advisory is disable SSL-VPN. Disabling webmode is not a valid workaround.

CVE-2023-27997 / FG-IR-23-097 (Family B): FortiOS 7.2.0-7.2.4, 7.0.0-7.0.11, 6.4.0-6.4.12, 6.2 through 6.2.13, 6.0 through 6.0.16. Fixes start at 7.2.5, 7.0.12, 6.4.13, 6.2.14, 6.0.17.

A box can be patched for 27997 and still sit in 21762 range, or the reverse. Inventory must record the exact get system status build. Both CVEs are in CISA KEV. That is not a vibe. That is a homework assignment.

Compensating controls if you cannot patch this afternoon
  • Disable SSL-VPN if it is not required.
  • Restrict portal source addresses to known egress.
  • Prefer architectures that do not need a world-open portal.
  • Keep hunting the URIs above even after the patch. Recon does not read your change ticket.

If the portal was reachable and unpatched

Do not treat "process restarted" as clean. Fortinet's own guidance after these pre-auth RCEs has included upgrade plus compromise assessment. Rotate secrets the firewall could have seen (LDAP bind, RADIUS, VPN PSKs, local users) if a hit is plausible.

On the FortiGate, follow current vendor IR notes, not this paragraph alone. Typical review points from public write-ups:

  • Unexpected files under SSL-VPN content / language paths
  • Unexpected administrators or API users
  • Configuration changes in the window
  • Leftovers under /tmp
  • Unexpected reads of /data/config/*.gz (that is the implant's job in this tree)
  • Whether the device was upgraded in place without a rebuild after a suspected pre-auth RCE

Mark each asset against the matrix:

  • Kit-exact: SKU + build match, SSL-VPN reachable - hunt first.
  • Kit-near: SKU matches, adjacent build - still hunt; wrong offsets often crash.
  • CVE-open, kit-miss: vulnerable per advisory, SKU not in the 53 - public clients still exist.
  • Patched + reachable during the window: historical compromise assessment.
  • SSL-VPN off / unreachable: this pack is out of operational scope.

Hunt the URIs on every portal VIP, not only kit-exact boxes.

The kit is on GitHub

The tree is public: Fortigate-SSL-VPN-Exploit-Kit (catalog). Recovered as found. I did not write it. Appendix is the file map. Research and detection only.

Evidence of a capability is not proof of a hit on a given serial. Proof is logs, crash correlation, callbacks, or disk artifacts. If SSL-VPN was Internet-facing and unpatched while these CVEs were already KEV, residual risk remains even without a matching log line.

Someone packed a catalog-scale FortiGate SSL-VPN RCE kit covering most common D/E/F appliances on FortiOS 6.0 through early 7.4, using two public, critical, previously exploited vulnerabilities. The intended outcome is code execution on the firewall and theft of /data/config/*.gz. Your exposure is defined by which FortiGates existed, which builds they ran, and whether SSL-VPN was reachable - not by how impressive 179 looks in a table.