← Back to Feed CACHED · 2026-10-16 06:59:12 · CACHE_KEY CVE-2025-61624
CVE-2025-61624 · CWE-22 · Disclosed 2026-04-14

FortiOS CLI auto-script path traversal enabling arbitrary file write/delete as root

ASSESSED — NOISGATE
Vendor
—
—
—
Reassessed
—
—
—
Verdict: —
Do you agree?
01 · The Real Story

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.

"Vendor says MEDIUM; APT-grade malware says otherwise. Admin-to-root on your perimeter firewall is HIGH."
02 · The Attack Path

5 steps from start to impact.

STEP 01

Obtain FortiOS admin CLI access

The attacker acquires admin-level CLI credentials for the target FortiGate. In the documented CL-STA-0954 campaign, initial access came via CVE-2024-47575 (unauthenticated RCE on FortiManager's FGFM protocol, TCP/541). Other realistic vectors include credential stuffing against exposed management interfaces (the FortiBleed campaign demonstrated ~86K valid FortiGate credentials in the wild), or LDAP/RADIUS credential theft.
Conditions required:
  • 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)
Where this breaks in practice:
  • 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
Detection/coverage: Failed SSH/HTTPS login attempts in FortiOS event logs; TACACS+/RADIUS authentication audit trails; FortiAnalyzer anomalous admin session alerts
STEP 02

Create path-traversal auto-script object

The attacker creates a 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.
Conditions required:
  • Admin profile with read-write permissions on system.auto-script (default super_admin has this)
  • CLI access (SSH or console)
Where this breaks in practice:
  • 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
Detection/coverage: FortiGuard IPS signature FG-VD-59270.0day; configuration change audit logs (diagnose debug config-error-log); FortiAnalyzer config diff alerts showing auto-script objects with ../ in names
STEP 03

Achieve arbitrary file write as root

The traversal places attacker-controlled content at any writable filesystem location with root ownership. The attacker targets startup scripts, cron paths, or loader locations under /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).
Conditions required:
  • Successful path traversal from step 2
  • Target filesystem path is writable (confirmed: /data2/, /tmp/ are writable on FortiOS)
Where this breaks in practice:
  • 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
Detection/coverage: Host-based file integrity checks against known-good FortiOS filesystem snapshots; fnsysctl ls -la output comparison
STEP 04

Execute PEERSTITCH injector on the underlying OS

The written payload executes with root privileges on the underlying Linux OS. PEERSTITCH (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.
Conditions required:
  • Root-level code execution on the FortiOS underlying Linux OS
  • Target daemons (miglogd, iked) are running — they always are on a production FortiGate
Where this breaks in practice:
  • 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
Detection/coverage: Volatile memory inspection: check /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 syslogd
STEP 05

Persistent memory-resident implant with covert IPC

PEERSTITCH applies three ARM64 NOP patches (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).
Conditions required:
  • Successful ptrace injection from step 4
  • Known offsets for the target FortiOS version's miglogd/iked binaries
Where this breaks in practice:
  • 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
Detection/coverage: ARM64 text segment integrity verification at known offsets (base + 0x106F7B8, base + 0x1072E20, base + 0x109A570, base + 0x135102C); kernel syscall auditing for cross-process /proc/<pid>/mem writes between miglogd and iked PIDs
03 · Compensating Control

1
HIGH 8.0→MEDIUM 5.5
SEVERITY REDUCED
Deploy FortiGuard virtual patch FG-VD-59270.0day immediately — Fortinet provides IPS signature FG-VD-59270.0day in FMWP database update 25.120 that blocks the path traversal pattern in auto-script object names at the CLI parsing layer. This is a vendor-provided compensating control that does not require a firmware upgrade. Deploy within the noisgate mitigation SLA of 30 days for HIGH-severity findings, though given confirmed exploitation, treat this as urgent — deploy within 7 days. Ensure FortiGuard IPS license is active and signatures are current.
2
HIGH 8.0→MEDIUM 5.0
SEVERITY REDUCED
Restrict admin CLI access to dedicated management VLAN and jumpbox — Limit SSH and HTTPS management access to FortiGate devices to a hardened jumpbox on a dedicated out-of-band management VLAN. Use config 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.
3
HIGH 8.0→HIGH 8.0
Audit for PEERSTITCH IOCs on all FortiGate devices — Run volatile memory checks on every FortiGate in your fleet: inspect /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.
4
HIGH 8.0→MEDIUM 6.0
SEVERITY REDUCED
Enable MFA on all FortiGate admin accounts — Configure FortiToken or RADIUS-based MFA for all administrative accounts. This raises the bar for credential-based initial access (step 1 of the attack path) by requiring a second factor even if passwords are compromised via FortiBleed-style credential leaks. Apply within 30 days.
5
HIGH 8.0→IGNORE 0.0
SEVERITY REDUCED
Upgrade to fixed firmware (FortiOS 7.4.10+ or 7.6.5+) — The definitive remediation is upgrading to a patched FortiOS release. FortiOS 7.4.10 and 7.6.5 sanitize auto-script object names to prevent path traversal. Organizations on 6.4, 7.0, or 7.2 branches must migrate — no backport fix exists. Schedule within the noisgate remediation SLA of 180 days for HIGH findings. Test in a lab environment first; coordinate maintenance windows for HA pairs.
What doesn't work
  • 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.
04 · Intelligence Metadata

The supporting signals.

In-the-Wild StatusConfirmed 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 AvailabilityNo 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.
EPSS0.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 StatusNot 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 VectorCVSS: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 VPR7.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 VersionsFortiOS: 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 VersionsFortiOS 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 ExposurePer 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 ResearcherDiscovered 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.

  1. Fortinet PSIRT Advisory FG-IR-26-122
  2. Unit 42 — PEERSTITCH FortiGate Implant Analysis
  3. NVD — CVE-2025-61624 Detail
  4. CIS Advisory — Multiple Fortinet Vulnerabilities (2026-035)
  5. Tenable Nessus Plugin 306463 — FG-IR-26-122
  6. Cybersecurity News — Fortinet Vulnerabilities / PEERSTITCH
  7. Strix.ai — CVE-2025-61624 Details
  8. BleepingComputer — CISA Fortinet Exploited Flaws Warning
05 · The Call

Final Verdict
↑ UPGRADED to HIGH (8.0/10)

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.

06 · Verification

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.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/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