The hotel manager who discovers the guest registry lets him rewrite every lock in the building — and the thieves already know
CVE-2025-61624 is a path traversal in the FortiOS CLI system.auto-script engine. The auto-script object name is not sanitized, so a name containing traversal sequences like ../../../../setup places the script body at any filesystem location as root. This gives an authenticated administrator (PR:H) arbitrary file write and delete on the underlying Linux OS. Affected: FortiOS 6.4 (all), 7.0 (all), 7.2 (all), 7.4.0–7.4.9, 7.6.0–7.6.4; also FortiPAM 1.0–1.7.0, FortiProxy 7.0–7.6.4, and FortiSwitchManager 7.0.0–7.2.7. Fixed in FortiOS 7.4.10 and 7.6.5.
Fortinet rates this MEDIUM (6.0) based on the CVSS vector AV:L/AC:L/PR:H/UI:N/S:U/C:N/I:H/A:H, which is technically correct in isolation — the attacker needs admin CLI access. But this rating is dangerously misleading in context. Unit 42 documented CL-STA-0954 (UNC5820) chaining CVE-2024-47575 → this CVE to deploy PEERSTITCH, a memory-resident ARM64 implant that injects into miglogd and iked daemons via ptrace, leaves zero disk artifacts, opens no ports, and makes no outbound connections. The campaign compromised a telecom MSP and exfiltrated configurations, credentials, and private keys for 500+ managed FortiGate firewalls. A 6.0 does not capture what this CVE enables on a fleet of perimeter firewalls.
5 steps from start to impact.
Obtain FortiOS admin CLI access
- Valid admin credentials or chaining with a separate initial-access vulnerability (e.g., CVE-2024-47575)
- Network reachability to the FortiOS management interface (SSH, HTTPS, or console)
- Management interfaces should be restricted to a dedicated OOB VLAN or jumpbox — but many orgs expose them
- CVE-2024-47575 was patched Oct 2024 and KEV-listed; organizations current on FortiManager patches reduce this vector
Create path-traversal auto-script object
system.auto-script configuration object with a crafted name containing directory traversal sequences (e.g., ../../../../tmp/payload). Because FortiOS does not sanitize the object name, the script body will be written to an arbitrary filesystem path as root when the configuration is committed. The CLI command is a standard config system auto-script / edit / set script sequence — no special tooling required.- Admin profile with read-write permissions on system.auto-script (default super_admin has this)
- CLI access (SSH or console)
- Minimal — the exploitation primitive is trivial once admin CLI access is obtained
- FortiGuard virtual patch FG-VD-59270.0day (FMWP db update 25.120) blocks the traversal pattern if IPS signatures are current
diagnose debug config-error-log); FortiAnalyzer config diff alerts showing auto-script objects with ../ in namesAchieve arbitrary file write as root
/data2/ or /tmp/. In the PEERSTITCH campaign, files were staged under /data2/template/ and included a five-stage payload chain: pM.js (environment prep), a.js/index.js (Emscripten runtime), a.wasm/index.wasm (WebAssembly module), b.js/ipssem.js (orchestrator), and dd/lldprx (the native ARM64 ELF injector).- Successful path traversal from step 2
- Target filesystem path is writable (confirmed:
/data2/,/tmp/are writable on FortiOS)
- FortiOS filesystem is partially read-only, limiting targets — but critical paths like
/data2/and/tmp/are writable - File integrity monitoring on FortiOS is limited to firmware verification, not arbitrary file auditing
fnsysctl ls -la output comparisonExecute PEERSTITCH injector on the underlying OS
lldprx) is a 64-bit ARM64 ELF binary statically linked against glibc. It iterates /proc/ to discover miglogd (logging daemon) and iked (VPN daemon) PIDs, attaches via ptrace(PTRACE_SEIZE), reads process memory layouts from /proc/<pid>/maps, allocates a 16,384-byte RWX region via mmap shellcode injection, and writes a 1,344-byte hook payload into the target process memory.- Root-level code execution on the FortiOS underlying Linux OS
- Target daemons (miglogd, iked) are running — they always are on a production FortiGate
- None — ptrace is available to root, and the target daemons are essential services that are always running
- No EDR or runtime protection exists inside FortiOS to block ptrace-based injection
/proc/<pid>/maps for anonymous 16,384-byte regions with rwxp permissions in miglogd and iked; diagnose debug crashlog read for Signal 11 (SIGSEGV) crashes in miglogd, iked, or syslogdPersistent memory-resident implant with covert IPC
0xAA0003E0 / MOV X0, X0) at hardcoded offsets in the target daemon's .text segment and installs a 20-byte trampoline redirect into the RWX hook buffer. The implant monitors traffic for markers (TCP port 8550, IP 169.254.0.1) and uses /proc/<pid>/mem writes to pass session tokens between miglogd and iked via circular ring buffers. No files on disk, no listening ports, no outbound connections. The implant survives until the daemon process restarts (i.e., reboot or firmware upgrade).- Successful ptrace injection from step 4
- Known offsets for the target FortiOS version's miglogd/iked binaries
- Version-specific offsets mean the implant must be tailored per FortiOS build — but APT actors have demonstrated this capability
- A firmware upgrade or device reboot clears the implant (no disk persistence) — but the attacker can re-deploy if the underlying CVE is unpatched
/proc/<pid>/mem writes between miglogd and iked PIDsconfig system interface to bind management access to a specific interface and trusted-host entries under admin accounts. This breaks the attack path at step 1 by reducing the reachable surface for credential-based initial access. Apply within 30 days per the noisgate mitigation SLA./proc/<pid>/maps for anonymous 16,384-byte rwxp regions in miglogd and iked processes. Check diagnose debug crashlog read for Signal 11 crashes. Review configuration for system.auto-script objects containing ../ sequences. Compare file hashes under /data2/template/ against known-good baselines. This does not mitigate the vulnerability but detects active compromise. Perform immediately.- Web Application Firewall (WAF) rules — CVE-2025-61624 is exploited via the FortiOS CLI (SSH/console), not via HTTP/HTTPS web requests. WAF signatures cannot inspect SSH sessions or CLI command parsing.
- FortiClient EMS endpoint protection — FortiClient protects endpoints behind the firewall, not the firewall OS itself. No FortiClient agent runs inside FortiOS to detect ptrace injection or filesystem tampering.
- Network IDS/IPS monitoring of transit traffic — The exploitation occurs within the management plane CLI session, not in transit data-plane traffic. Standard network IDS positioned to monitor traffic flowing through the firewall will not see CLI commands. Only the FortiGuard IPS virtual patch (which operates at the CLI parsing layer) is effective.
- Rebooting the device — While a reboot clears the PEERSTITCH memory-resident implant, it does not patch the underlying vulnerability. The attacker can re-deploy if they retain admin access and the CVE remains unpatched.
The supporting signals.
| In-the-Wild Status | Confirmed exploited. Fortinet PSIRT marks "Known Exploited: Yes" in FG-IR-26-122. Unit 42 documented exploitation by CL-STA-0954 / UNC5820 against a telecom MSP (intrusion: September 2024; published: October 2026). The campaign used CVE-2025-61624 to escalate from FortiOS admin to root for PEERSTITCH deployment. |
|---|---|
| PoC Availability | No public standalone PoC. No results on pocindex.io, GitHub, ExploitDB, or Nuclei templates for CVE-2025-61624 as of October 2026. The exploitation technique (path traversal in system.auto-script object names) is described in sufficient detail in the Unit 42 report that a skilled operator could reproduce it, but no turnkey exploit code is public. |
| EPSS | 0.00535 (0.535%) — low predicted exploitation probability in the next 30 days. This underestimates reality given confirmed APT exploitation; EPSS likely lags because the vuln requires admin access and has no public PoC driving mass scanning. |
| KEV Status | Not listed in CISA Known Exploited Vulnerabilities catalog as of 2026-10-16, despite Fortinet confirming exploitation. DISA has issued IAVA 2026-A-0093 requiring DoD remediation. |
| CVSS Vector | CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:U/C:N/I:H/A:H — Base 6.0. Attack is local (CLI), low complexity, requires high privileges (admin), no user interaction. Scope unchanged. No confidentiality impact (write/delete only), high integrity and availability impact. Temporal score 5.4 per Fortinet. |
| Tenable VPR | 7.3 (High) — 98.23rd percentile. Tenable's Vulnerability Priority Rating incorporates threat intelligence and rates this significantly above the CVSS base score, corroborating an upgrade from MEDIUM. |
| Affected Versions | FortiOS: 6.4.x (all), 7.0.x (all), 7.2.x (all), 7.4.0–7.4.9, 7.6.0–7.6.4. FortiPAM: 1.0–1.7.0. FortiProxy: 7.0.x (all), 7.2.x (all), 7.4.0–7.4.11, 7.6.0–7.6.4. FortiSwitchManager: 7.0.0–7.0.6, 7.2.0–7.2.7. Branches 6.4, 7.0, and 7.2 have no backport fix — migration to 7.4.10+ or 7.6.5+ is required. |
| Fixed Versions | FortiOS 7.4.10, 7.6.5. FortiPAM 1.7.1 (or 1.8+). FortiProxy 7.4.12, 7.6.5. FortiSwitchManager 7.0.7, 7.2.8. |
| Internet Exposure | Per Shodan/Bitsight data from the June 2026 FortiBleed incident, approximately 320,000+ FortiGate devices are internet-facing globally. The FortiBleed campaign verified ~86,644 working admin/VPN credentials across these devices. Management interface exposure is widespread despite best-practice guidance. |
| Reporting Researcher | Discovered internally by Fortinet and through the CL-STA-0954 incident investigation by Palo Alto Networks Unit 42 researchers. Published in the Unit 42 report dated October 14, 2026. |
Sources.
- Fortinet PSIRT Advisory FG-IR-26-122
- Unit 42 — PEERSTITCH FortiGate Implant Analysis
- NVD — CVE-2025-61624 Detail
- CIS Advisory — Multiple Fortinet Vulnerabilities (2026-035)
- Tenable Nessus Plugin 306463 — FG-IR-26-122
- Cybersecurity News — Fortinet Vulnerabilities / PEERSTITCH
- Strix.ai — CVE-2025-61624 Details
- BleepingComputer — CISA Fortinet Exploited Flaws Warning
Why this verdict
- Active APT exploitation confirmed: CL-STA-0954/UNC5820 used this CVE to deploy the PEERSTITCH memory-resident implant on FortiGate firewalls at a telecom MSP, exfiltrating configurations, credentials, and private keys for 500+ managed devices. This is not theoretical — the chain has been weaponized and operationalized by a sophisticated threat actor with deep FortiOS internals knowledge.
- Role multiplier — network edge appliance (floor: HIGH→CRITICAL): FortiOS runs exclusively on FortiGate firewalls, FortiProxy, and FortiSwitchManager — 100% of the installed base is network perimeter infrastructure. Root compromise of a FortiGate yields full traffic visibility, VPN credential theft, network segmentation bypass, and lateral movement enablement. The demonstrated blast radius is fleet-scale (500+ firewalls). Per the deployment-role floor rule, this component canonically occupies the high-value network-edge role, which sets a CRITICAL floor. However, we downgrade to HIGH based on the PR:H constraint and chain-dependency evidence below.
- PR:H limits standalone reachability (downgrade from CRITICAL floor): The standalone CVE requires admin CLI access — a significant prerequisite. The documented chain requires CVE-2024-47575 (FortiManager unauth RCE, patched October 2024, KEV-listed) for initial access. Organizations that patched FortiManager to 7.0.13/7.2.8/7.4.5/7.6.1+ — releases available for over 18 months — are not reachable via the proven chain. Per FortiBleed data, ~86K of ~320K internet-facing FortiGates had compromised credentials, but credential-based access requires a separate failure (weak passwords, no MFA on admin, exposed management interface). This narrows the immediately-exploitable population enough to justify one notch below CRITICAL.
- Tenable VPR corroboration: Tenable's VPR of 7.3 (98.23rd percentile) independently agrees this belongs in the HIGH tier, well above the vendor's MEDIUM 6.0. CIS rates this HIGH for large and medium government entities.
- Security boundary violation is the key enabler: This CVE is the precise step that transforms admin-level firewall configuration access into root OS-level code execution. Without it, an attacker with admin creds can misconfigure the firewall. With it, they can deploy invisible, memory-resident malware that no FortiOS-level tool can detect. This boundary break is what makes PEERSTITCH possible.
Why not higher?
Despite the CRITICAL floor for network edge appliances, we hold at HIGH (8.0) because the standalone CVE requires pre-existing admin CLI access (PR:H), the only documented exploitation chain depends on CVE-2024-47575 which has been patched and KEV-listed for 18+ months, no public standalone PoC exists to enable mass exploitation, and EPSS at 0.535% reflects low near-term broad exploitation probability. The population reachable without a separate initial-access failure is materially constrained.
Why not lower?
Keeping the vendor's MEDIUM (6.0) would be negligent. This CVE has been actively exploited by a sophisticated threat actor to achieve fleet-scale compromise of perimeter firewalls. The MEDIUM rating treats this as a theoretical local privilege escalation while ignoring that (a) FortiGate management interfaces are widely exposed, (b) admin credentials are routinely compromised, and (c) the blast radius on a perimeter firewall is categorically different from a workstation. Tenable VPR 7.3, CIS HIGH rating, and DISA IAVA 2026-A-0093 all reject the MEDIUM classification.
Crowdsourced verification payload.
Run from an auditor workstation with SSH access to the target FortiGate. Requires admin-level SSH credentials. Usage: bash cve-2025-61624-check.sh 10.0.1.1 or with custom port/user: bash cve-2025-61624-check.sh 10.0.1.1 2222 fwadmin. No root needed on the auditor host.
#!/usr/bin/env bash
# CVE-2025-61624 Version Checker for FortiOS
# Checks whether FortiOS firmware is vulnerable to FG-IR-26-122
# Exit codes: 0=PATCHED 1=VULNERABLE 2=UNKNOWN
set -euo pipefail
HOST="${1:?Usage: $0 <host> [ssh-port] [admin-user]}"
PORT="${2:-22}"
USER="${3:-admin}"
echo "[*] Connecting to $HOST:$PORT as $USER ..."
RAW=$(ssh -o ConnectTimeout=10 -o StrictHostKeyChecking=accept-new \
-o BatchMode=yes -p "$PORT" "${USER}@${HOST}" \
"get system status" 2>/dev/null) || {
echo "UNKNOWN — SSH connection to $HOST:$PORT failed"
exit 2
}
# Parse version string (e.g. "Version: FortiGate-100F v7.4.8,build...")
VERLINE=$(echo "$RAW" | grep -i '^Version' | head -1)
if [[ -z "$VERLINE" ]]; then
echo "UNKNOWN — could not find version line in system status output"
exit 2
fi
# Extract numeric version
VERSION=$(echo "$VERLINE" | grep -oP 'v\K[0-9]+\.[0-9]+\.[0-9]+')
if [[ -z "$VERSION" ]]; then
echo "UNKNOWN — could not parse version number from: $VERLINE"
exit 2
fi
MAJOR=$(echo "$VERSION" | cut -d. -f1)
MINOR=$(echo "$VERSION" | cut -d. -f2)
PATCH=$(echo "$VERSION" | cut -d. -f3)
echo "[*] Detected FortiOS version: $VERSION (major=$MAJOR minor=$MINOR patch=$PATCH)"
# Also check for IOCs while we're connected
echo "[*] Checking for PEERSTITCH IOCs (auto-script path traversal) ..."
ASCRIPT=$(ssh -o ConnectTimeout=10 -o BatchMode=yes -p "$PORT" "${USER}@${HOST}" \
"show system auto-script" 2>/dev/null) || ASCRIPT=""
if echo "$ASCRIPT" | grep -q '\.\./'; then
echo "[!] WARNING: Path traversal sequences detected in system.auto-script objects!"
echo "[!] This device may be actively compromised. Investigate immediately."
fi
# Version comparison
if (( MAJOR < 6 )); then
echo "UNKNOWN — FortiOS $VERSION predates known affected range"
exit 2
elif (( MAJOR == 6 && MINOR == 4 )); then
echo "VULNERABLE — FortiOS $VERSION (6.4.x all affected; no backport. Migrate to 7.4.10+ or 7.6.5+)"
exit 1
elif (( MAJOR == 7 && MINOR == 0 )); then
echo "VULNERABLE — FortiOS $VERSION (7.0.x all affected; no backport. Migrate to 7.4.10+ or 7.6.5+)"
exit 1
elif (( MAJOR == 7 && MINOR == 2 )); then
echo "VULNERABLE — FortiOS $VERSION (7.2.x all affected; no backport. Migrate to 7.4.10+ or 7.6.5+)"
exit 1
elif (( MAJOR == 7 && MINOR == 4 )); then
if (( PATCH >= 10 )); then
echo "PATCHED — FortiOS $VERSION (fixed in 7.4.10)"
exit 0
else
echo "VULNERABLE — FortiOS $VERSION (upgrade to 7.4.10+)"
exit 1
fi
elif (( MAJOR == 7 && MINOR == 6 )); then
if (( PATCH >= 5 )); then
echo "PATCHED — FortiOS $VERSION (fixed in 7.6.5)"
exit 0
else
echo "VULNERABLE — FortiOS $VERSION (upgrade to 7.6.5+)"
exit 1
fi
elif (( MAJOR > 7 )) || (( MAJOR == 7 && MINOR > 6 )); then
echo "PATCHED — FortiOS $VERSION (post-affected branch)"
exit 0
else
echo "UNKNOWN — FortiOS $VERSION unrecognized; verify manually against FG-IR-26-122"
exit 2
fi