CVE-2026-104286 is an unauthenticated arbitrary file write in FortiMail, reachable over the management GUI with a single crafted request and no credentials. Fortinet published it on 1 October 2026 as FG-IR-26-175, already exploited in the wild. CISA added it to the Known Exploited Vulnerabilities catalog the same day, with a three-day remediation deadline.

An unauthenticated file write does not sound like the worst class of bug until you follow what one write buys an attacker on an appliance you cannot run an endpoint agent on. The answer, in the observed intrusions, is persistence inside every process on the device.

[INFO]
Primary sources: Fortinet PSIRT advisory FG-IR-26-175 (published 1 October 2026, updated 7 October) and the NVD record for CVE-2026-104286. Exploitation and additional detail from the Cloud Security Alliance research note, SOCRadar, and watchTowr's analysis as relayed by Cybersecurity Dive. The write-to-execution chain is reconstructed from the advisory's own indicators and is flagged below where it is inference rather than vendor statement.
◈ interactive artifact
One Write, Preloaded Everywhere
From an unauthenticated request to ld.so.preload persistence. The control step is inferred from the IOCs, not confirmed by Fortinet - the demo says so.

//The Bug

Fortinet classifies it as a path traversal (CWE-22) compounded by improper neutralisation of a NULL byte (CWE-158), in the FortiMail GUI component. Together those let an unauthenticated attacker send a crafted HTTP or HTTPS request whose path escapes the directory it was meant to stay in, and write an arbitrary file to an arbitrary location. The NULL-byte handling is what makes the traversal work where naive filtering would otherwise stop it.

Affected and fixed versions, from the advisory:

8.0.0 through 8.0.1 - fixed in 8.0.2
7.6.0 through 7.6.6 - fixed in 7.6.7
7.4.0 through 7.4.8 - fixed in 7.4.9
7.2.0 through 7.2.9 - no fix on this branch, migrate to 7.4 or above

FortiMail Cloud was remediated by Fortinet on 5 October 2026, so cloud customers need take no action. Everyone running the appliance does.

//The CVSS Record Is the Story

This site has written before about how the same CVE can carry two different scores from NVD and the vendor. This one looks, at first, like it does not have that problem: both the NVD page and Fortinet say 9.8 critical, with the vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H.

Look closer and the divergence is still there - it is just quieter. NVD has not assigned a score of its own. The only CVSS entry in the NVD record is Fortinet's, carried through and tagged as a secondary source. There is no primary NVD assessment. And in carrying Fortinet's data, NVD dropped two things: the temporal metrics Fortinet published alongside the base vector (E:P/RL:O/RC:C - proof-of-concept maturity, an official fix available, confirmed report), and the second weakness, CWE-158. NVD records only CWE-22.

So the lesson from the PivotC2 piece inverts here. There the two sources disagreed on the number and you had to read both. Here they agree on the number precisely because one of them is echoing the other, and the record is still lossy: the authoritative-looking NVD page is a lightly degraded copy of the vendor advisory. If you want the full picture - the temporal context, both weakness classes, the exact affected builds - the Fortinet advisory is the document, and NVD is the convenient but incomplete mirror.

A small version discrepancy worth knowing

The machine-readable data inside the NVD record additionally lists the 7.0 branch as affected. The human-readable Fortinet advisory and the secondary trackers do not mention a 7.0 branch at all. That is almost certainly an NVD data artifact rather than a real affected branch, but if you run FortiMail 7.0 it is worth confirming your status against Fortinet directly rather than trusting either the presence or the absence of it in one feed.

//From File Write to Persistence

The intrusions that triggered the advisory show what the write was used for. The attacker dropped a malicious shared library - liblog.so - and added it to /data/etc/ld.so.preload. The dynamic linker consults that file on every process launch and loads the listed libraries first, into everything. That turns a one-shot file write into code running inside legitimate processes, automatically, for as long as the file stays there.

Alongside it: an attacker account reported as archive234 pointed at a remote host, and a cron entry under /migadmin running a shell command on a schedule. Fortinet describes the impact as executing unauthorized code or commands; watchTowr's analysis, relayed through Cybersecurity Dive, calls it trivial to exploit and says the write lets an attacker run commands on the device.

The single cleanest detection here does not require knowing the exploit at all. An ld.so.preload entry referencing a library you did not install is a high-fidelity sign of compromise on any Linux-based system, and it is exactly the artifact this campaign leaves. No network signature was published at disclosure, so host-level file integrity is where this gets caught.

//What To Do

Patch, now. It is on the KEV list with a three-day federal deadline for a reason: unauthenticated, remote, exploited, and on a device that sits in the mail path. Upgrade to 8.0.2, 7.6.7 or 7.4.9, or migrate off 7.2.

While patching, reduce exposure. Fortinet's workarounds are to disable IBE (identity-based encryption) and to keep the webmail and management GUI off the public internet or restricted to trusted networks. If a WAF sits in front of the device, block POST requests to /ibe that contain ../.

If it was exposed, hunt before you trust the patch. Check /data/etc/ld.so.preload, look for an archive234 account and unexpected cron entries under /migadmin, and check for outbound connections to the two IPs below. Patching closes the door; it does not remove a preload entry that is already there.

[IOC]
Indicators from FG-IR-26-175, corroborated via SOCRadar and the CSA research note. Verify file hashes against the Fortinet advisory before using them as blocking indicators.

CVE: CVE-2026-104286 - unauthenticated arbitrary file write (CWE-22 + CWE-158), CVSS 9.8
Advisory: FG-IR-26-175 (1 October 2026); CISA KEV add 1 October 2026

IPs: 79.141.169[.]187, 45.129.0[.]192
Attacker account: archive234 -> remote 79.141.169[.]187, dir /uploads
Persistence: /data/etc/ld.so.preload referencing /data/lib/liblog.so
Dropped/modified: /data/bin/webconsole, /data/bin/mailservice, /bin/smit, /data/etc/httpd.conf, /data/migadmin.tar.gz
Cron: shell command under /migadmin
Behavioural: IBE decrypter BufferException "Invalid Base64 Encoding", failed wildcard-email logins
Workaround: disable IBE; remove GUI from internet; WAF-block POST to /ibe containing ../

//Sourcing and Uncertainty

The vulnerability class, the CWE pair, the CVSS vector, the affected and fixed versions, the advisory ID and dates, and the exploited-in-the-wild status all come from Fortinet FG-IR-26-175 and the NVD record. The KEV add date is from CISA via NVD. The persistence artifacts and IOCs come from the advisory as reproduced by SOCRadar and the Cloud Security Alliance note.

What is inferred, not confirmed. Fortinet did not publish a step-by-step write-to-code-execution chain. The ld.so.preload persistence path is reconstructed from the published IOCs and is a well-understood technique, but the exact mechanics of turning the file write into execution are an inference supported by watchTowr's analysis, not a Fortinet statement. Treat the control step in the demo as reconstructed. That /ibe is the specific vulnerable endpoint is also an inference from the WAF workaround wording, flagged as such by the CSA note.

What is unknown. Fortinet gave no exploitation start date, no victim count and no attribution, and none has been established since. A widely shared headline claiming "98% already exploited" is a roundup artifact with no primary basis - discard it. No GreyNoise or Rapid7 scan telemetry for this CVE could be found, so there are no credible exploitation-volume figures to cite. The file hashes circulating come from SOCRadar's reproduction rather than a reading of the advisory itself, which is why they are not printed here as blocking indicators without the caveat to verify them.

The interpretation is mine: that the NVD-versus-vendor story here is not a score gap but a lossy mirror, and that the preload entry is the detection worth building around because it survives whatever the exact exploit turns out to be.