# Checkmk security release of 11 Nov 2026 (CVE-2026-118965, CVE-2026-120495, CVE-2026-121374): CybaVerse detection pack

For UK MSPs running Checkmk (often with remote sites at client premises), Microsoft Sentinel and Microsoft Defender XDR. Built 11 Nov 2026. Primary sources read 11 Nov 2026 between 13:06 and 13:10 GMT.

**Patch now.** Upgrade Checkmk 2.5.0 to 2.5.0p19 or above and 2.4.0 to 2.4.0p40 or above. Sites on 2.3.0 are end of life and Checkmk will not fix them: move them to 2.4.0p40 or 2.5.0p19. **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 11 Nov 2026, GMT) |
|---|---|---|
| Release | Checkmk 2.5.0p19 and 2.4.0p40 posted 11 Nov 2026 at 10:43:37 and 10:43:49 GMT (forum topic times). Both list werks 17994 and 22120 under "all editions" and 22624 under "commercial editions". | [2.5.0p19 release](https://forum.checkmk.com/t/release-checkmk-stable-release-2-5-0p19/60834), [2.4.0p40 release](https://forum.checkmk.com/t/release-checkmk-stable-release-2-4-0p40/60835) (13:06) |
| Pre-announcement | Posted 6 Nov 2026 10:54 GMT: three remote code execution fixes "rated to have a critical severity of 9.4", release on 11 Nov, 2.3.0 "will not receive a security patch", and a recommendation to update first to 2.4.0p39 or 2.5.0p18 ("This reduces the risk of unrelated breaking changes that could delay the update."). It also says "All editions of Checkmk are affected by this security patch" (see edition note below). | [pre-announcement](https://forum.checkmk.com/t/upcoming-checkmk-security-release-2-4-0p40-and-2-5-0p19/60794) (13:06) |
| CVE-2026-118965 | Werk 22120 "Code execution through compromised remote site" (werk date 29 Oct 2026, the authoring date). The central site queries remote sites for discovered host labels and writes the response to disk; the file name was not sanitised, so "a malicious remote site was able to write arbitrary files on the central site leading to code execution". Who is affected: "Every setup with potentially untrusted remote sites". Editions: all five (Community, Pro, Ultimate, Cloud, Ultimate MT). "This was reported via our security disclosure" (no reporter named). CWE-22. | [werk 22120](https://checkmk.com/werk/22120), [CVE record](https://www.cve.org/CVERecord?id=CVE-2026-118965) (13:06) |
| CVE-2026-120495 | Werk 22624 "Code execution through Robotmk HTML log test service" (werk date 2 Nov 2026). A test case name in agent data is used to build the HTML log folder; the path was not validated, allowing path traversal of an HTML file with user defined content and code execution. After the fix logs are "no longer created outside of ~/var/robotmk/html_logs". Who is affected: a monitored host has to be compromised to add crafted agent output, "for example by creating a malicious agent plug-in or spool file. This usually needs root privileges on a host monitored with Checkmk", and either automatic service discovery is on for the host or an admin confirms the Robotmk services. Editions: **commercial only** (Pro, Ultimate, Cloud, Ultimate MT). The werk does not say who found it. CWE-23. | [werk 22624](https://checkmk.com/werk/22624), [CVE record](https://www.cve.org/CVERecord?id=CVE-2026-120495) (13:06) |
| CVE-2026-121374 | Werk 17994 "Kubernetes: Arbitrary file write and code execution via excluded node roles" (werk date 3 Nov 2026). Node roles from "Cluster resource aggregation > Exclude nodes based on their role" reached the special agent's command line unseparated, so a role could be read as an option such as `--profile` and write files, including an executable Python script, anywhere the site user can write. Who is affected: "All sites". The attacker needs a user who may edit rules in at least one folder; by default that includes "Normal monitoring user" with folder permissions; the site does not need to monitor Kubernetes. "This issue was found during internal review." Editions: all five. CWE-88. | [werk 17994](https://checkmk.com/werk/17994), [CVE record](https://www.cve.org/CVERecord?id=CVE-2026-121374) (13:06) |
| Checkmk score | All three: **9.4 CRITICAL**, `CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:H/SI:H/SA:H`, on each werk and as the CNA metric in each CVE record (CNA: Checkmk). This is Checkmk's own rating. | Werks, cveawg.mitre.org API (13:06) |
| Affected versions | Each werk: 2.5.0, 2.4.0 and 2.3.0 (EOL). Each CVE record: 2.5.0 lessThan 2.5.0p19, 2.4.0 lessThan 2.4.0p40, and 2.3.0 affected, defaultStatus unaffected. Fixed in 2.5.0p19 and 2.4.0p40 (and 3.0.0b1, "Not yet released"). **No branch older than 2.3.0 is listed.** | Werks, CVE records |
| CVE records | Published 11 Nov 2026: CVE-2026-121374 10:45 GMT (updated 10:51), CVE-2026-120495 10:46 GMT, CVE-2026-118965 10:48 GMT. No CISA ADP container. No credits field. | cveawg.mitre.org API (13:06) |
| NVD | All three status **Deferred**, published 11:17 GMT. Only metric: Checkmk's CVSS 4.0 9.4 (security@checkmk.com, type Secondary). **No NVD (Primary) score** and no CPE configuration. | [NVD API 2.0](https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=CVE-2026-118965) (13:06) |
| CISA KEV | **None of the three is listed** in KEV catalog version 2026.11.10, dateReleased 10 Nov 2026 19:03 GMT, 1779 entries. That catalog predates the CVE records. The catalog has no Checkmk entries at all. | [KEV JSON](https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json) (13:06) |
| Exploitation and IOCs | Checkmk's werks and posts make no statement about exploitation either way and publish no IOCs. This pack contains no IOCs. | Werks, release posts |
| Fix code | Checkmk's public source (GitHub, branches 2.4.0 and 2.5.0, commits dated 11 Nov 2026 10:33 GMT) shows the 22120 and 17994 fixes: synced label files must stay in `var/check_mk/discovered_host_labels` and end in `.mk`; node roles are now passed as `--cluster-aggregation-exclude-node-role=<role>` instead of `--cluster-aggregation-exclude-node-roles <roles...>`; `--profile` only writes under `~/tmp/check_mk/debug`. The 22624 commit in the public repository holds only the werk text (the Robotmk check is commercial code). | [Checkmk source on GitHub](https://github.com/Checkmk/checkmk) (13:08) |

Edition note: the pre-announcement says all editions are affected by the security patch, while werk 22624 and both release posts put CVE-2026-120495 in the commercial editions only, and the CVE record for it names no editions. We follow the werk: Checkmk Community is listed for CVE-2026-118965 and CVE-2026-121374, not for CVE-2026-120495.

Dates note: the werk pages show 29 Oct (22120), 2 Nov (22624) and 3 Nov (17994). These are authoring dates. The public release date is 11 Nov 2026 (release posts).

### Paths used in this pack (all from Checkmk documentation, the werks or Checkmk's public source)

| Path | Source |
|---|---|
| Site home `/omd/sites/<site>`, versions `/omd/versions/<version>`, site link `~/version` pointing to `../../versions/2.5.0p19.community` | [omd_basics](https://docs.checkmk.com/latest/en/omd_basics.html), [update](https://docs.checkmk.com/latest/en/update.html) |
| `omd version` prints `OMD - Open Monitoring Distribution Version 2.5.0p19.community` | [update](https://docs.checkmk.com/latest/en/update.html) |
| Edition suffixes: 2.4.0 cre, cee, cce, cse, cme; 2.5.0 community, pro, ultimate, ultimatemt, cloud | Checkmk source `cmk/ccc/version.py` (2.4.0 and 2.5.0 branches); docs show cre, cee, cme, community, pro, ultimate |
| `~/var/check_mk/discovered_host_labels/` | Checkmk source `cmk/utils/paths.py`, `host_label_sync.py` |
| `~/var/robotmk/html_logs` | Werk 22624 |
| `~/tmp/check_mk/debug` | Werk 17994 |
| Rules: `~/etc/check_mk/conf.d/wato/<folder>/rules.mk`; rule option `cluster_aggregation_exclude_node_roles` (older `cluster-aggregation-exclude-node-roles`), special agent `kube` | [cmk_commandline](https://docs.checkmk.com/latest/en/cmk_commandline.html), [distributed_monitoring](https://docs.checkmk.com/latest/en/distributed_monitoring.html); Checkmk source `cmk/plugins/kube/rulesets/special_agent.py` |
| Linux agent: `/usr/lib/check_mk_agent/plugins`, `/usr/lib/check_mk_agent/local`, `/var/lib/check_mk_agent/spool` | [agent_linux](https://docs.checkmk.com/latest/en/agent_linux.html), [spool_directory](https://docs.checkmk.com/latest/en/spool_directory.html) |
| Windows agent: `C:\ProgramData\checkmk\agent\plugins`, `\local`, `\spool`; program files in `C:\Program Files (x86)\checkmk\service\`; `cmk-agent-ctl` | [agent_windows](https://docs.checkmk.com/latest/en/agent_windows.html), [spool_directory](https://docs.checkmk.com/latest/en/spool_directory.html) |
| Packages `check-mk-community-2.5.0p19`, `check-mk-raw-2.4.0p40` | [update](https://docs.checkmk.com/latest/en/update.html) |

**UNVERIFIED:** the 2.3.0 edition suffixes (we assume the 2.4.0 set); how rules.mk stores the role list on a live site (we read it as a Python literal); which parent binaries live under `/omd/` on your build; how Defender names Checkmk packages; Syslog command line formats.

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

**Checkmk says:** upgrade to 2.5.0p19 or 2.4.0p40. Before that, Checkmk recommends updating to 2.4.0p39 or 2.5.0p18 to reduce the risk of unrelated breaking changes. Sites on 2.3.0 or lower should upgrade to an actively supported version. Questions go to security@checkmk.com. Checkmk lists no workaround. The fixes need no configuration change.

**CISA:** none of the three CVEs is in the KEV catalog (version 2026.11.10, 19:03 GMT). The CVE records have no CISA ADP entry yet.

**We say (our advice, not Checkmk's or CISA's):**
1. Find every Checkmk server and site (Q1, Q1b, asset register). On each server, as root or the site user, run `bash scripts/check-checkmk.sh --site /omd/sites/<site>` or `bash scripts/check-checkmk.sh --version "$(omd version)"`, or collect versions into a CSV for `--inventory`. Upgrade every VULNERABLE site today.
2. **Central sites first, if you run remote sites at client premises.** Until a central site is patched, treat every remote site you do not fully control as untrusted (werk 22120's condition). Patch the central site before or together with the remote sites.
3. **Review who may edit rules.** Werk 17994 needs only a user who may edit rules in one folder, which by default includes Normal monitoring users with folder permissions. Remove rule editing from client facing or shared accounts you do not need, then run `bash scripts/check-checkmk-kube-rules.sh --path /omd/sites/<site>/etc/check_mk/conf.d/wato` (read-only) for Kubernetes rules with roles that start with a dash.
4. **Commercial editions:** until patched, do not accept Robotmk services you did not expect, and check which hosts have automatic service discovery on (werk 22624's conditions).
5. Hunt with Q2 to Q7b and the Sigma rules: odd files in the site home, HTML outside `~/var/robotmk/html_logs`, Kubernetes agent runs with `--profile`, shells started by the site user, and new agent plug-ins or spool files on monitored hosts. These are our own patterns. They do not detect the vulnerabilities themselves.
6. If anything looks wrong: keep a copy of the site (for example `omd backup`) for evidence before you change it, rotate Checkmk user and automation secrets and the passwords stored in the site, review recent rule changes in the audit log, and contact Checkmk support.

## Pack contents

| Path | What it is |
|---|---|
| `kql/checkmk-cve-2026-118965-120495-121374-hunting.kql` | 15 KQL hunts: Q1, Q1b, Q1c, Q1d, Q2, Q2b, Q3, Q4, Q4b, Q5, Q5b, Q6, Q6b, Q7, Q7b |
| `sigma/*.yml` | 6 Sigma rules (our patterns) |
| `sigma/converted/` | Sigma to Kusto conversions: no pipeline, microsoft_xdr, microsoft_365_defender, sentinel_asim, azure_monitor |
| `scripts/check-checkmk.sh`, `scripts/Check-Checkmk.ps1` | Offline version checkers (bash and PowerShell 7, byte identical output) |
| `scripts/check-checkmk-kube-rules.sh`, `scripts/Check-CheckmkKubeRules.ps1` | Offline rules.mk checker for Kubernetes node roles that start with a dash (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 | Checkmk versions in use, from processes running out of `/omd/versions/<version>/` | Inventory |
| Q1b | Checkmk packages in Defender software inventory (**UNVERIFIED** naming) | Inventory |
| Q1c | Ingest check for the three CVEs in Defender's knowledge base | Inventory |
| Q1d | Monitored hosts running the Checkmk agent (`cmk-agent-ctl`, Windows agent folder) | Inventory |
| Q2 | Non `.mk` files written in `~/var/check_mk/discovered_host_labels/` (CVE-2026-118965) | Ours |
| Q2b | Script or library type files (.py, .sh, .pl, .so, .pth) written in a site home outside its tmp folder (CVE-2026-118965, CVE-2026-121374) | Ours |
| Q3 | HTML files written in a site home outside `~/var/robotmk/html_logs/` (CVE-2026-120495) | Ours |
| Q4 | `agent_kube` runs with `--profile`, or with a role starting with a dash in the fixed option form (CVE-2026-121374) | Ours |
| Q4b | Files written by `agent_kube` outside `~/tmp/check_mk/debug/` (CVE-2026-121374) | Ours |
| Q5 | Shells and download or network tools started by a site account (fill `siteUsers`) | Ours |
| Q5b | Site account command lines not seen in the previous 30 days | Ours |
| Q6 | New or changed files in the Linux agent plug-in, local and spool folders (CVE-2026-120495) | Ours |
| Q6b | The same for the Windows agent folders | Ours |
| Q7 | Sentinel Syslog: the Q4 strings in forwarded audit or process logs (**UNVERIFIED** format) | Ours |
| Q7b | Sentinel Syslog: su, sudo or sshd activity naming a site account (**UNVERIFIED** format) | Ours |

Notes:
- Werk 22120's sync copies the remote site's file times onto the written files, so use event times, not file modified times, when you triage Q2 and Q2b.
- In Checkmk's public source the Kubernetes rule never adds `--profile`, which is why Q4 treats any `--profile` on an `agent_kube` command line as worth a look.
- Defender tables use `Timestamp`; Sentinel tables use `TimeGenerated`.

### Sigma rules

| Rule | Hunt | Converts on Microsoft pipelines? |
|---|---|---|
| `lnx_file_checkmk_discovered_host_labels_non_mk.yml` (linux file_event) | Q2 | Yes, all four |
| `lnx_file_checkmk_html_outside_robotmk_logs.yml` (linux file_event) | Q3 | Yes, all four |
| `lnx_proc_checkmk_kube_agent_profile.yml` (linux process_creation) | Q4 | Yes, all four |
| `lnx_proc_checkmk_site_user_shell.yml` (linux process_creation) | Q5 | Yes, all four |
| `lnx_file_checkmk_agent_plugin_spool.yml` (linux file_event) | Q6 | Yes, all four |
| `win_file_checkmk_agent_plugin_spool.yml` (windows file_event) | Q6b | Yes, all four, with a quirk |

Conversion quirks (checked with sigma-cli, enforced by `tests/run_all.sh`): every rule converts on all five targets, but **azure_monitor maps the five Linux rules to the Windows `SecurityEvent` table**, which holds no Linux events, so use the microsoft_xdr, microsoft_365_defender or sentinel_asim output (or the KQL) for Linux. azure_monitor also turns the Windows rule's `contains` into `endswith "...\plugins*"`, which will not match; fix it to `contains` or use Q6b.

## Version checker

Strictly read only and offline. It compares version strings you pass, a CSV you saved, or where a site's `version` link points (read with `readlink`; nothing is run). No network, no file writes, no payloads. It never runs `omd` itself: you pass its output.

```
bash scripts/check-checkmk.sh --version 2.4.0p39.cre --name cmk-01
bash scripts/check-checkmk.sh --version "$(omd version)"
bash scripts/check-checkmk.sh --site /omd/sites/mysite
bash scripts/check-checkmk.sh --inventory checkmk-inventory.csv
pwsh -File scripts/Check-Checkmk.ps1 -Inventory checkmk-inventory.csv
```

CSV header: `name,version`. Versions may be `2.4.0p39`, `2.4.0p39.cre`, `2.5.0p19.community` or the whole `omd version` line. The edition suffix decides CVE-2026-120495; without it that CVE is reported UNKNOWN.

| Verdict | Meaning | Exit |
|---|---|---|
| PATCHED | 2.5.0p19 or above, or 2.4.0p40 or above | 0 (only when every row is PATCHED) |
| VULNERABLE | 2.5.0 below p19, 2.4.0 below p40, or any 2.3.0 (end of life, no fix) | 1 |
| OUT OF RANGE | Branch not listed by Checkmk (for example 2.2.0, 2.6.0, 3.0.0). No claim either way. | 2 (no VULNERABLE rows) |
| UNKNOWN | Pre-release i or b builds (such as 2.5.0b3, 3.0.0b1), daily builds, 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, no version link | 4 |

Each row also gives a per CVE result: PATCHED, VULNERABLE, NOT AFFECTED (CVE-2026-120495 on Community, per werk 22624) or UNKNOWN. Worst row wins: VULNERABLE, then OUT OF RANGE, then UNKNOWN.

### rules.mk checker (our pattern)

`bash scripts/check-checkmk-kube-rules.sh --path /omd/sites/<site>/etc/check_mk/conf.d/wato` reads every `rules.mk` below that folder and reports any Kubernetes node role that starts with a dash (such as `--profile`). Exit 0 clean, 1 suspicious, 4 usage or read error. A role list that itself contains a `]` is cut short; review those by hand. Equivalent quick grep (read only): `grep -rn -- "exclude_node_roles" /omd/sites/<site>/etc/check_mk/conf.d/wato --include=rules.mk` and look for list items starting with `-`. A patched site no longer passes such a role as an option, but a rule like that still tells you someone tried.

## Tests

`bash tests/run_all.sh` runs ShellCheck, PSScriptAnalyzer, the bash tests, Pester (including byte for byte parity between each pair of checkers), guards against network and file write primitives in the scripts, a FIXTURE_ONLY marker check, an RFC 5737 only check for fixture IPs, no IP literals and no ports in KQL and Sigma, a no em or en dash check, wording guards (no banned names, credit only as Checkmk states it, Critical and 9.4 only as Checkmk's rating, no KEV deadline claim, no exploitation status claims, no guessed details, no claims about unlisted branches, every hunt and rule 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 Q7b and all Sigma rules are our patterns. They look for exposure and for behaviour after possible compromise; they will not show the vulnerabilities being triggered. Checkmk published no IOCs.
- Defender for Endpoint on Linux must be on the Checkmk servers and monitored hosts for Q1, Q2 to Q6; Syslog formats for Q7 and Q7b are UNVERIFIED.
- The checker only knows the branches Checkmk lists. It never claims a branch is affected or not affected beyond Checkmk's tables.
- Fixture data is synthetic (FIXTURE_ONLY) and uses RFC 5737 addresses only.
