FortiBleed Update: the FBI and Secret Service Advisory, and the FortiMail Zero-Day CVE-2026-104286

Two Fortinet stories are running at once, and the headlines have started to treat them as one. They are not. FortiBleed is a credential-compromise campaign against FortiGate firewalls and SSL VPN gateways, with no CVE and no patch. CVE-2026-104286 is a genuine code defect in FortiMail that was exploited before Fortinet had fixes. I can find no source that links the two, and the mechanisms have nothing in common. What they share is the problem: an internet-facing Fortinet management or access surface that someone could reach.

I covered FortiBleed’s origin in Two Ways to Lose a VPN Gateway. This post covers what has changed since, then the FortiMail bug.

FortiBleed: what is new

The official count and the advisory

On 6 October the FBI and US Secret Service published a joint advisory (ic3.gov CSA 2026/261006) saying more than 86,000 internet-facing FortiGate firewalls and VPN gateways have been compromised across 194 countries. The precise figure, reported by The Register and BleepingComputer, is 86,644, and it is SOCRadar’s verification count that the agencies cite rather than a tally of their own. When I wrote the August post the public estimates ran from about 30,000 devices with confirmed working credentials (SOCRadar’s earlier count) to roughly 75,000 (Kevin Beaumont and Hudson Rock). The newer number sits above both. Treat it as a snapshot: SecureWorld reports that the IP addresses in the advisory were active between 18 June and 23 July.

The attack chain, now spelled out

The advisory and the coverage of it describe the same sequence:

  1. Scan for exposed FortiGate SSL VPN portals with automated scripts.
  2. Run credential stuffing and password spraying with credentials from earlier breaches and infostealer logs.
  3. On devices that fall, extract password hashes and crack them offline on GPU clusters. BleepingComputer names Hashcat and Hashtopolis.
  4. Sort and rank the results. The attackers’ exposed backend contained scripts to validate credentials, filter out honeypots, identify the organisation and rank targets by revenue and network structure.
  5. Sell the access. Initial access brokers pass it to ransomware affiliates, and the advisory names INC/Lynx and Payload. SOCRadar counted at least 12 confirmed ransomware attacks in July.

That fits the hashing problem I described in August: FortiOS moved administrator passwords from salted SHA-256 to PBKDF2 in 7.2.11, 7.4.8 and 7.6.1, but an existing password keeps its SHA-256 hash until that administrator logs in again after the upgrade. The FBI now lists “enforcing PBKDF2 for administrator password storage” among its recommendations, and eSecurityPlanet’s summary puts it plainly: a firmware upgrade alone does not complete the migration.

Lockouts and persistence

The new operational detail is what the attackers do once inside. According to the advisory, they create administrator accounts that were not there before, and in some cases use them to delete existing administrators or change their passwords. The result is that the legitimate owners get locked out of their own firewall. Deleted accounts also support lateral movement, and Active Directory is the usual next target.

Account names to look for, from the coverage and from the Singapore CSA advisory (AD-2026-007): forticloud-sync, support_fortinet, IT_Manager, forticloud, fortiuser, fortinet-support and fortinet-tech-support. The name forticloud-sync is the same one I flagged in the Gunra ransomware advisory post. A different actor, the same camouflage: a local super-admin named to look like a vendor service.

What Fortinet says

Fortinet attributes the activity to reused credentials and brute force rather than a new vulnerability, and points administrators to its guidance on password hashing. SecureWorld reports that Fortinet’s PSIRT tied the campaign to credentials reused from earlier incidents, including CVE-2026-24858, CVE-2025-59718 and CVE-2025-59719. I have not seen that linkage in a Fortinet document myself, so I am passing it on as reported, not confirmed.

Checking your own devices

I ran these read-only checks on my own FortiGate 70G, which is on FortiOS 7.6.7. The output is trimmed, and I have redacted the hash and swapped my management ranges for placeholder ones.

FGT-70G-HUB # show system admin
config system admin
    edit "admin"
        set vdom "root"
        set trusthost1 192.168.1.0 255.255.255.0
        set trusthost2 192.168.2.0 255.255.255.0
        set accprofile "super_admin"
        set password ENC PB2<redacted>
    next
end

FGT-70G-HUB # get system admin status
username: admin
login local: console
login vdom: root
login access profile: super_admin

FGT-70G-HUB # show system api-user
config system api-user
end

FGT-70G-HUB # show full-configuration system admin | grep password
        set force-password-change disable
        set password ENC PB2<redacted>

What to read from that:

  • show system admin lists every administrator. On a healthy device, every name is one you created. Mine has one account, and it is locked to two trusted host ranges, which is the minimum I would accept on anything with a reachable management interface.
  • get system admin status shows who is logged in now. Mine is my own console session.
  • show system api-user lists REST API keys. SecureWorld flags forgotten automation keys as an easy way back in because they survive a password reset. Mine is empty.
  • The password prefix is the hash type. PB2 is PBKDF2. SH2 is legacy SHA-256 and means that administrator never logged in after the upgrade. The grep password filter also matches force-password-change, so expect that extra line.

A PB2 prefix is not the whole answer. After a password is migrated, Fortinet keeps the previous SHA-256 hash in a hidden old-password field for backward compatibility. It does not show in the CLI or GUI, but it appears in a configuration backup taken by a super_admin, so an attacker with a backup has it. Fortinet’s technical tip says the purge setting removes those entries, and on my 70G that setting is off:

FGT-70G-HUB # show full-configuration system password-policy | grep login-lockout
    set login-lockout-upon-weaker-encryption disable

Disabled is the default, so a device can sit on current firmware with PB2 hashes and still carry the old values. To close both gaps, first make sure every administrator has a PBKDF2 hash. Either each one logs in once on the updated firmware, or a super_admin resets the password of any who will not:

config system admin
edit admin
set password NewLongRandomPassphrase2026!
end

The CLI will ask for the logged-in administrator’s current password, and show should then display PB2. Second, enable the purge:

config system password-policy
set login-lockout-upon-weaker-encryption enable
end

That is the name on FortiOS 7.6.7. Fortinet’s technical tip says the equivalent on 7.2.x and 7.4.x is login-lockout-upon-downgrade, and some secondary write-ups use the first name for every version. On an older build, run show full-configuration system password-policy | grep login-lockout as above to see which one it has. Once the setting is on, moving to firmware that does not support PBKDF2 will lock administrators out, so do not enable it on a device you might roll back.

Order matters

The advisory says remediation “may need more than patching and resetting Fortinet passwords”. The Singapore advisory and SecureWorld both warn that a factory reset or an early password reset destroys the evidence of what the intruder did. The sensible order is:

  1. Restrict management access first. Trusted hosts help, a local-in policy is better, and removing internet-facing administration entirely is best.
  2. Collect logs and a configuration backup before changing credentials.
  3. Terminate all administrator and VPN sessions.
  4. Reset every administrator and VPN password, enforce phishing-resistant MFA, and remove unrecognised accounts and API keys.
  5. Complete the PBKDF2 migration and purge the legacy hashes as above.
  6. Review domain controller logs for lateral movement. A firewall compromise often becomes an Active Directory incident.

FortiMail: CVE-2026-104286

What it is

Advisory FG-IR-26-175 covers CVE-2026-104286, CVSS 3.1 9.8 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H/E:P/RL:O/RC:C). The classes are CWE-22 (path traversal) and CWE-158 (improper neutralisation of NULL bytes). An unauthenticated attacker can write arbitrary files on the appliance through crafted HTTP or HTTPS requests to the web interface. Field Effect places the vulnerable code in the handling of Identity-Based Encryption (IBE) requests. Fortinet’s Product Security team found the bug internally, and by the time the advisory went out on 1 October it was already being exploited. CISA added it to KEV the same day with a federal deadline of 4 October.

On the claim that it lets attackers plant root code: Fortinet’s wording is that the flaw could lead to execution of unauthorised code or commands, and the advisory does not state a privilege level. Writing a file is also not the same thing as running one. The published indicators do include a cron job running as root, so I would assume a compromised appliance is fully owned.

When the exploitation started is unknown. The advisory’s own sample log entries are dated 20 July, according to Hard2bit’s reading of the STIX bundle, so exploitation may predate the disclosure by months. No victim count or attribution has been published.

Patch status

When this broke on 2 October, the fixed releases were listed as “upcoming”. The advisory was revised on 5 October and again on 7 October, and now lists a fix for every branch.

FortiMail branchAffectedFix
8.08.0.0 to 8.0.18.0.2 or above
7.67.6.0 to 7.6.67.6.7 or above
7.47.4.0 to 7.4.87.4.9 or above
7.27.2.0 to 7.2.9Move to the 7.4 branch or above

FortiMail Cloud is already remediated, on v7.6.7 GA or v8.0.2 GA, so Cloud customers need do nothing. Hard2bit reports release notes for 7.6.7 dated 2 October and for 7.4.9 dated 3 October. I could not independently confirm that an 8.0.2 download is available, so check the support portal for your branch before planning the window. The 7.2 branch has no fix of its own, which makes this a branch migration, not a patch.

Workarounds, and what they do not do

If you cannot upgrade yet, the advisory offers two mitigations. Disable IBE, or remove internet access to the FortiMail webmail interface and limit it to trusted private networks. IBE can be turned off in the GUI under Encryption, IBE, IBE Service, or from the CLI:

config system encryption ibe
set status disable
end

If a web application firewall sits in front of FortiMail, the advisory also suggests blocking POST requests to /ibe that contain ../. Be aware of the cost. IBE is what lets external recipients read encrypted mail, so switching it off or restricting it to private networks will break that workflow, and you should check who depends on it first.

None of this removes anything already on the box. Fortinet’s own advice, repeated by every write-up, is that a workaround or patch does not evict an attacker who is already in. I have not run any FortiMail commands for this post; this section is documented from Fortinet’s advisory and the write-ups listed below.

Indicators

From the advisory, defanged:

  • IP addresses: 79[.]141[.]169[.]187 and 45[.]129[.]0[.]192
  • A system event showing a root cron job that runs a shell command referencing /migadmin. Hard2bit describes it as dumping the appliance configuration into an HTML file under /migadmin/www and deleting it after 24 hours.
  • A configuration event adding an archive account named archive234, with a rotation to a remote destination at the first IP above, directory /uploads. The advisory does not explain the purpose. On a mail gateway, a remote archive destination reads as a way to move mail off the appliance, and I would treat it as the most serious indicator.
  • Files reported as added: /data/etc/ld.so.preload, /data/lib/liblog.so, /data/bin/webconsole and /data/bin/mailservice. Files reported as modified: /bin/smit, /data/etc/httpd.conf and /data/migadmin.tar.gz.
  • Encryption log lines showing IBE decryption errors with invalid Base64 input, and a burst of internal user login failures.

The archive account is a configuration change, so a file-hash comparison would not catch it, and it could survive a firmware upgrade. If you find anything, preserve logs and the configuration before changing the device. Hard2bit recommends rotating administrator, directory-service and email-reset credentials and considering a rebuild from a trusted image. There is no official Fortinet cleanup procedure that I could find. The directory-service credential is the one people forget: a mail gateway usually holds a bind account for your directory.

Why I am keeping them in one post

The two stories do not share a cause, but they do share a consequence. In both, a Fortinet appliance that holds a lot of trust (VPN and firewall credentials in one case, mail flow and directory credentials in the other) was reachable from the internet through a surface that did not need to be public. The pattern is the same one I have written about with FortiSandbox, FortiManager’s FGFM trust gap and FortiWeb’s RADIUS bypass. Patching helps with the code defects. It does nothing for a credential that is already known to the attacker.

What I would do, in order

  1. FortiGate administration first. Take management off the internet, check show system admin and show system api-user for anything you did not create, and confirm every administrator is on PB2 hashes.
  2. Turn on the legacy-hash purge once every administrator has a PBKDF2 hash, unless you might roll back to older firmware. It is off by default.
  3. If you run FortiMail, treat it as potentially compromised until you have checked. Look for the archive234 account, the root cron entry and the listed files before you patch. Then upgrade (on 7.2, move to the 7.4 branch) and disable IBE in the meantime if nobody needs it.
  4. Rotate what the appliances hold. That means FortiGate administrator and VPN passwords, and for FortiMail the administrator, directory-service and email-reset credentials.
  5. Plan MFA that is phishing-resistant. The advisory asks for it, and a one-time code alone does not meet that bar, according to SecureWorld’s reading.
  6. Send the logs somewhere the appliance cannot reach. Several intrusions I have covered this year cleared local logs before the final stage.

Sources