Someone left the mailroom door unlocked and attackers are already inside rewriting the building's blueprints
CVE-2026-104286 is a path traversal combined with improper NULL-byte neutralization (CWE-22 + CWE-158) in the Identity-Based Encryption (IBE) GUI component of Fortinet FortiMail. An unauthenticated attacker who can reach the appliance's HTTP/HTTPS listener sends a crafted request that writes arbitrary files to the underlying Linux filesystem — no credentials, no user interaction, no exotic race condition. The bug spans four major release trains: 8.0.0–8.0.1, 7.6.0–7.6.6, 7.4.0–7.4.8, and 7.2.0–7.2.9. Fixed versions are 8.0.2, 7.6.7, and 7.4.9; the 7.2 branch is EOL and must migrate to 7.4+. The advisory is tracked as FG-IR-26-175, disclosed October 1, 2026, and discovered internally by Gwendal Guégniaud of Fortinet's PSIRT.
Fortinet's CRITICAL / 9.8 rating is fully justified and may even understate urgency given the real-world context. This is not a theoretical bug sitting in a dark corner of a config panel — Fortinet's own advisory confirms active zero-day exploitation with published IOCs (dropped binaries in /data/lib/liblog.so, /data/bin/webconsole, /data/bin/mailservice, a weaponized ld.so.preload, and C2 callbacks to 79.141.169.187 and 45.129.0.192). CISA added it to the KEV catalog on October 1, 2026 with a federal remediation deadline of October 4 — a 72-hour window, among the tightest CISA has ever set. The attack requires zero authentication against a device class that by definition sits at the network perimeter processing every email your organization sends and receives. A public PoC (ShadowForge-Cyber, Python) appeared on sploitus the same day. The vendor score is not inflated; if anything the 9.8 doesn't capture the blast radius of owning an organization's email gateway.
5 steps from start to impact.
Locate internet-facing FortiMail IBE portal
- Target organization runs FortiMail with IBE enabled
- IBE GUI endpoint is reachable over HTTP/HTTPS from the internet or attacker's network position
- Organizations that disabled IBE are not reachable via this vector
- Appliances with management interface restricted to internal VLANs require internal network access first
http.title:"FortiMail" or Server: FortiMail identifies exposed instances. GreyNoise and Censys tags may flag scanning activity targeting FortiMail IBE endpoints.Send crafted path-traversal request with NULL-byte injection
../) combined with a NULL byte (%00) to bypass path sanitization. The NULL byte truncates the filename at the OS level while the application-level check passes the full string. No authentication token, session cookie, or CSRF token is required — the endpoint is fully unauthenticated.- HTTP/HTTPS connectivity to the FortiMail IBE endpoint
- Knowledge of the vulnerable URI path (publicly documented)
- WAF rules inspecting for path traversal sequences may block naive payloads, but NULL-byte variants often bypass standard rulesets
../ and %00 in URI paths. Fortinet has not published the exact URI, but the ShadowForge-Cyber PoC (cve-2026-104286.py) targets a known endpoint.Write malicious shared library and ld.so.preload
/data/lib/liblog.so) and create or modify /data/etc/ld.so.preload to point to it. This ensures the malicious library is loaded into every new process on the appliance. The attacker also modifies /data/etc/httpd.conf to persist across service restarts and drops additional binaries (webconsole, mailservice) for C2 communication.- Successful path traversal from step 2
- Write access to
/data/and/bin/paths on the FortiMail filesystem
- FortiMail's filesystem integrity monitoring (if enabled) could detect unexpected file modifications, but the appliance runs a stripped-down Linux — runtime integrity checking is limited
/data/lib/liblog.so (SHA-256: 8015f34dc84922b03688399d7f9fe7a00361789f7e420c7e2a2cdb23e75cef84), /data/etc/ld.so.preload, and /data/etc/httpd.conf modifications. Fortinet published seven file IOC hashes in the advisory.Achieve persistent code execution as root
ld.so.preload hijacked, every process on the appliance loads the attacker's shared library. The FortiMail appliance runs as root — there is no privilege boundary to escalate past. The attacker now has persistent, root-level code execution on the email gateway. Observed post-exploitation includes creation of rogue archive accounts (e.g., archive234) configured to exfiltrate email to attacker-controlled servers.- Malicious ld.so.preload and shared library written in step 3
- FortiMail services restart or new processes spawn (happens continuously during normal mail processing)
- None meaningful — the appliance runs as root by design, and mail processing continuously spawns new processes
archive account creation, unusual cron jobs referencing /migadmin, and administrator logout events not correlated with known admin activity.Establish C2 and exfiltrate email data
webconsole, mailservice) establish outbound C2 connections to attacker infrastructure (observed: 79.141.169.187, 45.129.0.192). From this position the attacker can read, modify, or redirect all email flowing through the gateway, harvest credentials from email content, pivot into the internal network, or use the trusted mail gateway to send convincing phishing to internal users.- Persistent root access from step 4
- Outbound network connectivity from the FortiMail appliance to attacker C2
- Egress filtering blocking outbound connections from the FortiMail appliance to unknown IPs would disrupt C2, though DNS-based or email-based exfiltration channels remain available from a mail gateway
79.141.169.187 and 45.129.0.192 at perimeter firewalls. Monitor for IBE decryption errors with invalid Base64 encoding in FortiMail logs — observed as an exploitation artifact.config system encryption ibe / set status disable / end on every FortiMail instance. This removes the vulnerable code path entirely. IBE-encrypted email delivery to external recipients will stop working, but the appliance continues to function as a mail gateway for all other use cases. This is Fortinet's recommended workaround. Given the CRITICAL verdict, deploy within the noisgate mitigation SLA of ≤3 days — but given active exploitation and KEV listing, deploy within hours, today. Walk the attack path: this breaks step 1 (IBE endpoint is no longer reachable) and eliminates all downstream steps.79.141.169.187 and 45.129.0.192 at all egress points. Add to SIEM/EDR blocklists. This disrupts the observed C2 channel for currently-known campaigns but does not prevent initial exploitation or C2 over alternative channels. Deploy immediately alongside the IBE disable.archive accounts, unexpected cron jobs referencing /migadmin, and outbound connections to the C2 IPs. If any IOC is found, treat the appliance as compromised — isolate, image, rebuild from clean firmware. CISA BOD 26-04 requires this triage for federal agencies by October 4.- Email gateway antivirus/antispam scanning — the vulnerability is in the IBE GUI web handler, not in mail processing. Scanning email content does not touch the vulnerable code path.
- FortiMail access profiles / admin role restrictions — the vulnerability is pre-authentication. Access profiles only govern authenticated admin sessions and have no bearing on this unauthenticated attack vector.
- Upstream MTA relay restrictions — the attack targets the HTTP/HTTPS web interface, not the SMTP listener. Restricting which MTAs can relay through FortiMail does not affect exploitability.
- Generic WAF path-traversal rules — the NULL-byte injection (CWE-158) component specifically defeats naive
../pattern matching. Standard WAF rules may block trivial traversal attempts but the NULL-byte variant is designed to bypass them. Do not rely on WAF alone.
The supporting signals.
| In-the-wild exploitation | Confirmed active zero-day exploitation at time of disclosure (Oct 1, 2026). Fortinet advisory FG-IR-26-175 marks 'Known Exploited: Yes' and publishes 7 file-hash IOCs plus 2 C2 IP addresses. Campaigns involve ld.so.preload hijacking, rogue archive account creation, and binary drops. No ransomware use identified at disclosure. |
|---|---|
| CISA KEV status | Listed October 1, 2026 — the same day as vendor disclosure. Federal remediation deadline: October 4, 2026 (72 hours). *Note: The user's intake data indicated KEV: No, which is incorrect per CISA KEV catalog.* |
| Proof-of-concept availability | Public PoC exists. ShadowForge-Cyber published a Python exploit (cve-2026-104286.py) on sploitus on Oct 1, 2026 — supports both command execution (-c) and arbitrary file read/write (-l/-o). Rated 96% confidence by sploitus. No named GitHub repo dedicated to this CVE was found on pocindex.io at time of assessment, but the sploitus listing references a functional weaponized tool. |
| EPSS score | Not yet calculated — CVE disclosed <48 hours ago. Given the active exploitation, unauthenticated attack vector, and PoC availability, expect EPSS to land in the 95th+ percentile once scored. |
| CVSS vector analysis | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H — the maximum-impact unauthenticated remote vector. Every metric is at its worst-case value except Scope (Unchanged). The vector accurately reflects the attack: network-reachable, trivial complexity, no auth, no user interaction, full CIA impact on the appliance. |
| Affected version ranges | FortiMail 8.0.0–8.0.1, 7.6.0–7.6.6, 7.4.0–7.4.8, 7.2.0–7.2.9. The 7.2 branch has no fix and must migrate to 7.4.9+. Spans ~4 years of releases. |
| Fixed versions | FortiMail 8.0.2, 7.6.7, 7.4.9. The 7.2.x train is end-of-fix; Fortinet directs migration to 7.4+. Check Fortinet Upgrade Path Tool for supported upgrade paths. |
| Exposure / scanning data | FortiMail appliances are email security gateways typically deployed at the MX perimeter. Exact Shodan/Censys counts for FortiMail are not as widely published as FortiGate (~150K+ internet-facing), but the IBE portal is architecturally intended for external access — organizations using IBE *must* expose the endpoint to email recipients. The related FortiBleed campaign (June 2026) demonstrated that Fortinet device exposure remains massive across 194 countries. |
| Disclosure timeline | October 1, 2026: Fortinet publishes FG-IR-26-175, CISA adds to KEV, BleepingComputer reports active exploitation. Zero-day — exploited before any patch was available to customers. |
| Researcher / attribution | Discovered internally by Gwendal Guégniaud of Fortinet's Product Security (PSIRT) team. Attacker attribution for active campaigns has not been publicly disclosed by Fortinet. |
Sources.
- BleepingComputer — Fortinet warns of critical FortiMail flaw exploited in zero-day attacks
- Fortinet PSIRT Advisories (FG-IR-26-175)
- CISA Known Exploited Vulnerabilities Catalog
- Rapid7 Vulnerability Database — CVE-2026-104286
- Hol.org — FortiMail unauthenticated path traversal hits CISA KEV
- SecurityOnline — FortiMail Path Traversal Flaw Exploited in the Wild
- Sploitus — ShadowForge-Cyber PoC for CVE-2026-104286
- Mallory.ai — Actively Exploited Critical FortiMail Arbitrary File-Write Flaw
Why this verdict
- Unauthenticated remote code execution with zero friction: The attack requires no credentials, no user interaction, and low complexity. The CVSS vector is AV:N/AC:L/PR:N/UI:N — the widest possible attack aperture. There is no authentication gate, session requirement, or race condition that narrows the attacker population. No downward adjustment.
- Active zero-day exploitation with published IOCs: This is not theoretical. Fortinet confirmed active campaigns at disclosure, published 7 file hashes and 2 C2 IPs, and CISA issued a 72-hour federal remediation deadline. Exploitation preceded patch availability. No downward adjustment; upward pressure from confirmed weaponization.
- Public PoC lowers the exploitation barrier further: The ShadowForge-Cyber Python exploit on sploitus provides turnkey command execution and file manipulation against vulnerable FortiMail instances. Any script kiddie with network access can now exploit this. No downward adjustment.
- Role multiplier: FortiMail is canonically a network edge appliance — 100% of production installs are email security gateways sitting at the MX perimeter. This is not a component that *sometimes* occupies a high-value role; it IS the high-value role. Compromising a FortiMail appliance yields: (1) all organizational email in transit — confidential data, credentials, regulated content (HIPAA, PCI, SOX); (2) a perimeter pivot point into the internal network; (3) the ability to inject malware or phishing from a trusted internal domain; (4) root-level access to the underlying Linux OS. The blast radius is fleet-scale for email trust and data-scale for content exposure. Per the deployment-role rule, since the affected component is definitionally a high-value-role component (network edge appliance, ≥10% — in fact 100% — of installs), the verdict floor is CRITICAL. The chain succeeds in this role without additional prerequisites.
- IBE exposure is architectural, not misconfiguration: Unlike management interfaces that *should* be internal-only, the IBE portal is designed to serve encrypted emails to *external recipients*. Organizations using IBE must expose this endpoint publicly. This is not a 'restrict to internal only' situation — the feature's purpose requires internet exposure. Disabling IBE is a valid compensating control but removes product functionality.
Why not higher?
A 9.8 is already near the CVSS ceiling. The only metric not at maximum is Scope (Unchanged vs. Changed). Since exploitation is contained to the FortiMail appliance itself — the attacker gains root on the box but does not automatically break out of a hypervisor or change the security authority of another system — Scope: Unchanged is technically accurate. A 10.0 would require Scope: Changed, which is not warranted here.
Why not lower?
Every friction point one might cite evaporates on inspection. 'Requires IBE enabled' — IBE is a core FortiMail feature, widely deployed. 'Requires internet exposure' — the IBE portal is architecturally intended for internet-facing deployment. 'No public PoC' — a functional Python exploit is already public on sploitus. 'Not yet exploited' — actively exploited as a zero-day with CISA KEV listing and a 72-hour federal deadline. There is no credible basis for downgrading below CRITICAL.
Crowdsourced verification payload.
Run this script from any Linux/macOS workstation that can SSH into your FortiMail appliances. Invoke as: bash check_cve-2026-104286.sh <fortimail_host> [ssh_port]. Requires SSH key or password access to a FortiMail admin account. The script checks the running firmware version and IBE status.
#!/usr/bin/env bash
# check_cve-2026-104286.sh — FortiMail path traversal (CVE-2026-104286) version check
# Usage: bash check_cve-2026-104286.sh <fortimail_host> [ssh_port]
# Requires: SSH access to FortiMail admin CLI
# Outputs: VULNERABLE / PATCHED / UNKNOWN
set -euo pipefail
HOST="${1:-}"
PORT="${2:-22}"
if [[ -z "$HOST" ]]; then
echo "Usage: $0 <fortimail_host> [ssh_port]"
exit 3
fi
# Grab system status from FortiMail CLI
STATUS=$(ssh -o ConnectTimeout=10 -o StrictHostKeyChecking=accept-new -p "$PORT" admin@"$HOST" "get system status" 2>/dev/null) || {
echo "UNKNOWN — SSH connection to $HOST:$PORT failed"
exit 2
}
# Extract version string (e.g., "v7.6.5")
VERSION=$(echo "$STATUS" | grep -i 'Version' | head -1 | grep -oP 'v[0-9]+\.[0-9]+\.[0-9]+' | head -1)
if [[ -z "$VERSION" ]]; then
echo "UNKNOWN — could not parse FortiMail version from output"
exit 2
fi
# Strip leading 'v'
VER="${VERSION#v}"
MAJOR=$(echo "$VER" | cut -d. -f1)
MINOR=$(echo "$VER" | cut -d. -f2)
PATCH=$(echo "$VER" | cut -d. -f3)
echo "Detected FortiMail version: $VERSION"
# Check IBE status
IBE_STATUS=$(ssh -o ConnectTimeout=10 -p "$PORT" admin@"$HOST" "show system encryption ibe" 2>/dev/null) || true
if echo "$IBE_STATUS" | grep -qi 'disable'; then
IBE_ENABLED="no"
echo "IBE status: DISABLED (mitigated)"
else
IBE_ENABLED="yes"
echo "IBE status: ENABLED (vulnerable endpoint reachable)"
fi
# Version comparison
# Vulnerable ranges:
# 8.0.0 - 8.0.1 (fixed: 8.0.2)
# 7.6.0 - 7.6.6 (fixed: 7.6.7)
# 7.4.0 - 7.4.8 (fixed: 7.4.9)
# 7.2.0 - 7.2.9 (no fix, must migrate)
VULN="no"
if [[ "$MAJOR" -eq 8 && "$MINOR" -eq 0 ]]; then
if [[ "$PATCH" -le 1 ]]; then
VULN="yes"
FIX="8.0.2"
fi
elif [[ "$MAJOR" -eq 7 && "$MINOR" -eq 6 ]]; then
if [[ "$PATCH" -le 6 ]]; then
VULN="yes"
FIX="7.6.7"
fi
elif [[ "$MAJOR" -eq 7 && "$MINOR" -eq 4 ]]; then
if [[ "$PATCH" -le 8 ]]; then
VULN="yes"
FIX="7.4.9"
fi
elif [[ "$MAJOR" -eq 7 && "$MINOR" -eq 2 ]]; then
VULN="yes"
FIX="7.4.9+ (7.2.x has no fix; must migrate)"
elif [[ "$MAJOR" -eq 7 && "$MINOR" -le 1 ]]; then
# 7.0.x and earlier — check if in vulnerable range per some sources
VULN="yes"
FIX="7.4.9+ (must migrate)"
fi
# Also check for IOCs
echo ""
echo "--- IOC spot check ---"
IOC_CHECK=$(ssh -o ConnectTimeout=10 -p "$PORT" admin@"$HOST" "fnsysctl ls /data/lib/liblog.so" 2>/dev/null) || IOC_CHECK=""
if echo "$IOC_CHECK" | grep -q 'liblog.so'; then
echo "WARNING: /data/lib/liblog.so EXISTS — possible compromise indicator!"
else
echo "No liblog.so IOC found (good)"
fi
IOC_PRELOAD=$(ssh -o ConnectTimeout=10 -p "$PORT" admin@"$HOST" "fnsysctl cat /data/etc/ld.so.preload" 2>/dev/null) || IOC_PRELOAD=""
if [[ -n "$IOC_PRELOAD" ]] && echo "$IOC_PRELOAD" | grep -q 'liblog'; then
echo "WARNING: ld.so.preload references liblog — LIKELY COMPROMISED!"
else
echo "No ld.so.preload IOC found (good)"
fi
echo ""
if [[ "$VULN" == "yes" ]]; then
if [[ "$IBE_ENABLED" == "no" ]]; then
echo "VULNERABLE (version $VERSION is affected, but IBE is disabled — attack surface mitigated)"
echo "Recommended: upgrade to $FIX when available"
exit 1
else
echo "VULNERABLE — FortiMail $VERSION is in the affected range and IBE is ENABLED"
echo "IMMEDIATE ACTION: disable IBE or restrict GUI access. Upgrade to $FIX"
exit 1
fi
else
echo "PATCHED — FortiMail $VERSION is not in the vulnerable range"
exit 0
fi