# Fortinet FortiManager CVE-2026-126261 (FG-IR-26-275): CybaVerse detection pack

For UK MSPs running FortiManager with FortiGates, Microsoft Sentinel and Microsoft Defender XDR. Built 10 and 11 Nov 2026. Primary sources read 11 Nov 2026 between 00:01 and 00:05 GMT.

**Patch now.** Upgrade FortiManager 8.0.0 to 8.0.1 or above, 7.6.0 through 7.6.7 to 7.6.8 or above, 7.4.0 through 7.4.5 to 7.4.6 or above, and 7.2.0 through 7.2.8 to 7.2.9 or above. **The KQL in this pack has NOT been run against a live tenant.** Test and tune every query before you rely on it.

## Verified facts

| Item | Detail | Source (read, GMT) |
|---|---|---|
| CVE | CVE-2026-126261 | All below |
| Advisory | Fortinet FG-IR-26-275, "FGFM elevation before registration password is verified". Published 10 Nov 2026 (timeline "2026-11-10: Initial publication"). CSAF revision 1, status final. | [FG-IR-26-275](https://fortiguard.fortinet.com/psirt/FG-IR-26-275) (00:01), Fortinet CSAF JSON (00:01) |
| Fortinet's summary | "An improper authorization vulnerability in FortiManager FGFM may allow an unauthenticated attacker that can reach the FGFM port to execute code or commands via crafted FGFM packets." | FG-IR-26-275 (00:01) |
| Weakness | CWE-285, Improper Authorization | CSAF, CVE record, NVD |
| Fortinet's other fields | Severity Critical. **Component: GUI** (recorded as published; the summary describes FGFM, and we do not interpret the difference). Impact: Execute unauthorized code or commands. Attack Type: Unauthenticated. Discovered: Internal. Known Exploited: No. Virtual Patch: No. | FG-IR-26-275 (00:01) |
| Fortinet score | **Critical, CVSSv3 9.0** on the advisory page (number only, no vector shown). Fortinet's CSAF gives 9.0 with vector `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H/E:U/RL:O/RC:C` (base metrics plus temporal metrics). | FG-IR-26-275, CSAF (00:01) |
| CVE record (cve.org) | CNA is Fortinet. CNA metric: baseScore **9** (9.0), baseSeverity CRITICAL, vector `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H/E:U/RL:O/RC:C`, the same as the CSAF. Published 10 Nov 2026 22:23 GMT, updated 22:36 GMT. No CISA ADP container yet. | [cveawg.mitre.org API](https://cveawg.mitre.org/api/cve/CVE-2026-126261) (00:01) |
| NVD | Shows **9.8** CRITICAL with the base vector only, `CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H`, attributed to psirt@fortinet.com, type Secondary. NVD status "Received": **NVD has not done its own analysis and has no NVD (Primary) score.** NVD published 10 Nov 2026 23:17 GMT. | [NVD API 2.0](https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=CVE-2026-126261) (00:01), [NVD page](https://nvd.nist.gov/vuln/detail/CVE-2026-126261) |
| Score note (our arithmetic) | The base metrics compute to 9.8 under CVSS 3.1, which is NVD's figure. Adding Fortinet's temporal metrics (E:U, RL:O, RC:C) computes to 8.5, not 9.0. We report Fortinet's 9.0 as published and do not reconcile it. In CVSS 3.1, E:U means Exploit Code Maturity: Unproven. | Our calculation from the published vectors |
| CISA KEV | **Not listed** in KEV catalog version 2026.11.10, dateReleased 2026-11-10T19:03:29Z (10 Nov 2026 19:03 GMT), 1779 entries. That catalog predates the CVE record (22:23 GMT). The catalog does list an older FortiManager CVE (CVE-2024-47575, added 23 Oct 2024); that is a different CVE. | [KEV JSON](https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json) (00:01) |
| IOCs | None. Fortinet published no indicators of compromise and no technical details. This pack contains no IOCs. | FG-IR-26-275 |
| Credit | Internally discovered by Fortinet (Fortinet Product Security team). | FG-IR-26-275 |

### Affected and fixed (Fortinet's table)

| Version | Affected | Fortinet solution | Fixed build first shipped (Fortinet release notes change log) |
|---|---|---|---|
| FortiManager 8.0 | 8.0.0 | Upgrade to 8.0.1 or above | 8.0.1 build 0189, initial release 2026-09-15 |
| FortiManager 7.6 | 7.6.0 through 7.6.7 | Upgrade to 7.6.8 or above | 7.6.8 build 3788, initial release 2026-10-22 |
| FortiManager 7.4 | 7.4.0 through 7.4.5 | Upgrade to 7.4.6 or above | 7.4.6 build 2588, initial release 2024-12-18 |
| FortiManager 7.2 | 7.2.0 through 7.2.8 | Upgrade to 7.2.9 or above | 7.2.9 build 1638, initial release 2024-12-12 |

Sources: FG-IR-26-275 and the CSAF agree on the table; the CVE record lists the same ranges with defaultStatus "unaffected". Builds and dates come from the "FortiManager X Release" and "Change Log" pages of each version's release notes on docs.fortinet.com (read 00:01 to 00:02 GMT).

Scope notes:
- **Every fixed release predates the advisory.** 7.2.9 and 7.4.6 shipped in December 2024; 8.0.1 and 7.6.8 shipped in September and October 2026. The resolved issues pages of all four releases (read 00:05 GMT) do not mention CVE-2026-126261 or FG-IR-26-275, and Fortinet does not say when the fix went in beyond naming these versions. We report the dates and make no further claim.
- **Only four branches are listed: 8.0, 7.6, 7.4 and 7.2.** Fortinet's advisory, CSAF and CVE record say nothing about FortiManager 7.0, 6.x or older. This pack makes no claim about them; the checker reports them OUT OF RANGE.
- **FortiManager Cloud and FortiAnalyzer are not listed** in the advisory, CSAF or CVE record. This pack makes no claim about them.

### FGFM port (Fortinet documentation)

Fortinet's FortiManager 8.0.0 [Incoming ports](https://docs.fortinet.com/document/fortimanager/8.0.0/fortimanager-ports/465971/incoming-ports) page lists "IPv4 FGFM management TCP/541" and "IPv6 FGFM management TCP/541 (starting in FortiManager 7.4.1) TCP/542". The [Communications Protocol Guide](https://docs.fortinet.com/document/fortimanager/8.0.0/fortigate-fortimanager-communications-protocol-guide/621612/protocol-components) says: "The FortiManager unit listens on TCP port 541 for an incoming session request." (Both read 00:01 GMT.)

## Fortinet's advice, CISA's position, and ours

**Fortinet says:** upgrade to the fixed release for your branch (table above). Fortinet lists no workaround and no virtual patch.

**CISA:** CVE-2026-126261 is not in the KEV catalog (version 2026.11.10, 19:03 GMT). The CVE record has no CISA ADP entry yet. CISA has issued no KEV action for this CVE.

**We say (our advice, not Fortinet's or CISA's):**
1. Find every FortiManager (asset register, Q1, Q1b) and run `scripts/check-fortimanager.sh --inventory` on the versions. Upgrade every VULNERABLE unit today.
2. **Restrict FGFM (TCP/541, and TCP/542 for IPv6) on FortiManager to the known IP addresses of the FortiGates it manages.** Fortinet documents the port; the restriction is our advice. Check with Q2 and Q2b that nothing else reaches it, especially from the internet.
3. Treat units on 7.0, 6.x or other unlisted branches as their own problem: Fortinet's advisory does not cover them. Confirm their status with Fortinet.
4. Hunt with Q2 to Q8: FGFM from unknown sources, device registrations from unknown peers, new admin accounts or logins, script runs and config pushes, and odd outbound connections. These are our own patterns. They do not detect the vulnerability.
5. If anything looks wrong: take a FortiManager backup for evidence, isolate FGFM, review the managed FortiGates' configuration revisions for changes you did not make, rotate FortiManager admin credentials, and contact Fortinet support.

## Pack contents

| Path | What it is |
|---|---|
| `kql/fortimanager-cve-2026-126261-hunting.kql` | 12 KQL hunts: Q1, Q1b, Q1c, Q2, Q2b, Q3, Q4, Q5, Q6, Q6b, Q7, Q8 |
| `sigma/*.yml` | 4 Sigma rules (our patterns) |
| `sigma/converted/` | Sigma to Kusto conversions: no pipeline, microsoft_xdr, microsoft_365_defender, sentinel_asim, azure_monitor |
| `scripts/check-fortimanager.sh`, `scripts/Check-FortiManager.ps1` | Offline version checkers (bash and PowerShell 7, byte identical output) |
| `tests/` | Bash and Pester tests with parity, fixtures, KQL parse check, `run_all.sh` |

### KQL hunts

| ID | What it does | Whose |
|---|---|---|
| Q1 | FortiManager firmware versions from FortiManager syslog (documented sw_version field). **UNVERIFIED** which messages carry it, and the syslog format in Sentinel. | Inventory |
| Q1b | FortiManager addresses your FortiGates talk FGFM to (TCP/541, TCP/542), from FortiGate traffic in CommonSecurityLog | Inventory |
| Q1c | Ingest check for CVE-2026-126261 in Defender's knowledge base (Defender does not inventory FortiManager appliances) | Inventory |
| Q2 | FGFM connections from public source addresses | Ours |
| Q2b | FGFM sources that are not your known FortiGates | Ours |
| Q3 | Defender XDR: Windows, macOS or Linux endpoints connecting to TCP/541 or TCP/542 | Ours |
| Q4 | FortiManager FGFM device registration (11005), invalid peer certificate (11007), connection up (11002) and offline mode (11004) from peers not on your FortiGate list | Ours |
| Q5 | Device inventory changes: autolink device (10116), reclaim device tunnel (10095), device replace (31012), and DVM text keywords (**UNVERIFIED**) | Ours |
| Q6 | New or changed admin accounts: setting changed (10029) with "admin", or "system admin" text (**UNVERIFIED** path text) | Ours |
| Q6b | Admin logins (10018, 10019) from a user and source pair not seen in the previous 30 days | Ours |
| Q7 | Script runs (scrmgr 14002), script and config installs (dm 21007, 21015, 21023), shell use (10049), CLI command execution (10113) | Ours |
| Q8 | Rare public destinations of FortiManager, from FortiGate traffic logs | Ours |

Notes:
- FortiManager log subtypes, message IDs and fields come from Fortinet's [FortiManager 7.6.8 Log Message Reference](https://docs.fortinet.com/document/fortimanager/7.6.8/log-message-reference/100000/event) and its [log types and subtypes](https://docs.fortinet.com/document/fortimanager/7.6.8/log-message-reference/238528/fortimanager-log-types-and-subtypes) page (read 00:02 GMT). The full ten digit log_id values are derived from Fortinet's documented scheme on the [event log message example](https://docs.fortinet.com/document/fortimanager/7.6.8/log-message-reference/39757/fortimanager-event-log-message-example) page: two digits for type, two for subtype, six for message ID (example 0001010018). We have not seen these exact log_id values in a live log.
- **UNVERIFIED:** that FortiManager syslog arrives in Sentinel's Syslog table as key=value text in SyslogMessage, and that FortiGate traffic arrives in CommonSecurityLog with DeviceVendor "Fortinet" and a DeviceProduct containing "Fortigate". Check both in your workspace and adjust the parsing.
- Fill the `fmgIPs` and `knownFortiGates` lists before running Q2, Q2b, Q4 and Q8. Q8 needs `fmgIPs`.
- Defender tables use `Timestamp`; Sentinel tables use `TimeGenerated`.

### Sigma rules

| Rule | Hunt | Converts on Microsoft pipelines? |
|---|---|---|
| `net_firewall_fgfm_public_source.yml` (category firewall) | Q2 | No: only without a pipeline |
| `fortimanager_fgfm_registration_peer_events.yml` (product fortimanager) | Q4 | No: only without a pipeline |
| `fortimanager_script_shell_config_push.yml` (product fortimanager) | Q7 | No: only without a pipeline |
| `win_net_fgfm_port_connection.yml` (Windows network_connection) | Q3 | Yes, all four, with quirks |

Conversion gaps and quirks (checked with sigma-cli, enforced by `tests/run_all.sh`):
- microsoft_xdr, microsoft_365_defender, sentinel_asim and azure_monitor have **no table mapping for the firewall category or for product fortimanager**, so three rules fail on those four pipelines (twelve documented gaps). The no-pipeline output gives generic field names (dst_port, src_ip, log_id) to map onto your own table; or use KQL Q2, Q4 and Q7.
- `win_net_fgfm_port_connection.yml`: microsoft_xdr and microsoft_365_defender drop the `Initiated` condition (direction is not filtered). sentinel_asim maps `Initiated: 'true'` to `NetworkDirection =~ "true"`, which will not match ASIM direction values; remove or fix that clause. azure_monitor maps to SecurityEvent `DestinationPort`, which needs Windows Filtering Platform auditing.
- The log_id values are strings on purpose (they keep their leading zeros in the raw log), so `sigma check` runs with the number_as_string validator excluded.
- Q1 to Q1c (inventory), Q2b and Q8 (lists and aggregation), Q5 and Q6 (keyword text) and Q6b (baseline join) are KQL only.

## Version checker

Strictly read only and offline. It compares version strings you pass or a CSV you saved. No network, no file writes, no payloads, and it never contacts Fortinet or a device.

```
bash scripts/check-fortimanager.sh --version 7.4.5 --name fmg-01
bash scripts/check-fortimanager.sh --inventory fortimanager-inventory.csv
pwsh -File scripts/Check-FortiManager.ps1 -Inventory fortimanager-inventory.csv
```

CSV header: `name,product,version`. Product is `fortimanager` (aliases fmg, FortiManager-VM64 and similar). Anything else (FortiManager Cloud, FortiAnalyzer, FortiGate) is UNKNOWN. Versions may be `7.4.6`, `7.4.6.2588` or `v7.4.6-build2588` (as `get system status` style strings often show it). Two part versions such as `7.4` are UNKNOWN.

| Verdict | Meaning | Exit |
|---|---|---|
| PATCHED | At or above Fortinet's fix in a listed branch (8.0.1, 7.6.8, 7.4.6, 7.2.9) | 0 (only when every row is PATCHED) |
| VULNERABLE | In Fortinet's ranges above | 1 |
| OUT OF RANGE | Branch not listed by Fortinet (for example 7.0, 6.4, 8.2). No claim either way. | 2 (no VULNERABLE rows) |
| UNKNOWN | Not FortiManager, no product, no version, or an unreadable version. Never reported as PATCHED. | 3 (no VULNERABLE or OUT OF RANGE rows) |
| usage or read error | Bad arguments, bad header, empty or missing file | 4 |

Worst row wins: VULNERABLE, then OUT OF RANGE, then UNKNOWN.

## Tests

`bash tests/run_all.sh` runs ShellCheck, PSScriptAnalyzer, the bash tests, Pester (including byte for byte parity between the two checkers), guards against network and file write primitives in the scripts, a FIXTURE_ONLY marker check, an RFC 5737 only check for fixture IPs, a no IP literal check for KQL and Sigma (private range filters only), a no em or en dash check, wording guards (no banned names, credit to Fortinet, 9.8 only as NVD's figure, Critical only as Fortinet's rating, no KEV deadline claim, no guessed details, only Fortinet-documented FGFM ports, no claims about unlisted branches, every hunt labelled), sandboxed checker runs (no network, read only filesystem, pack sha256 unchanged), an offline KQL parse check with Kusto.Language, sigma check, and sigma convert for all five targets compared with `sigma/converted/`. It stops at the first failure and ends with `run_all: ALL PASSED`.

## Limits

- The KQL in this pack has NOT been run against a live tenant. It parses offline against an assumed schema subset.
- Hunts Q2 to Q8 are our patterns. They look for exposure and for behaviour after possible compromise; they will not show the vulnerability being triggered. Fortinet has published no technical details.
- Log ingestion formats, full log_id values, DVM and admin keyword text and the CommonSecurityLog vendor strings are UNVERIFIED.
- The checker only knows the branches Fortinet lists. It never claims a branch is supported, unsupported, affected or not affected beyond Fortinet's table.
- Fixture data is synthetic (FIXTURE_ONLY) and uses RFC 5737 addresses only.
