我们的 AI 引擎 Neutron 在加州大学伯克利分校的 CyberGym 基准测试中取得了 97.1% 的成绩。 了解更多

深度解析

深度解析

Checkmk RCE:一个补丁修复三个严重漏洞(CVE-2026-121374)

Checkmk 的三个漏洞让规则编辑者、恶意远程站点或受入侵主机能以站点用户身份执行代码;已在 2.5.0p19 中修复。

TL;DR

  • Checkmk 2.5.0p19 和 2.4.0p40 修复了三个严重漏洞,每一个最终都会以站点用户身份执行代码。厂商于 2026 年 11 月 11 日发布了这两个修复版本。
  • 2.5 系列中低于 2.5.0p19 的所有站点,以及 2.4 系列中低于 2.4.0p40 的所有站点都受影响。版本 2.3.0 已停止支持,不会获得修复。
  • 三个漏洞的评级均为 CVSS v4.0 9.4 严重。目前没有公开的利用代码,也没有发现实际利用,截至 2026 年 11 月 11 日均未列入 CISA 的 KEV 目录。
  • 请升级到 2.5.0p19 或 2.4.0p40。如果无法升级,请限制规则编辑,并且不要将中心站点连接到不受信任的远程站点;限制条件见“如何修复?”。

我受影响吗?

版本条件适用于所有漏洞;其余条件分别适用于所列的各个 CVE:

  • 你运行的 Checkmk 站点是低于 2.5.0p19 的 2.5.0,或低于 2.4.0p40 的 2.4.0。版本 2.3.0 受影响且已停止支持。
  • 对于 CVE-2026-121374,至少有一个用户可以在至少一个文件夹中编辑规则。默认情况下,这包括对某个文件夹拥有权限的“Normal monitoring user”角色。
  • 对于 CVE-2026-118965,你的中心站点从你不完全信任的远程站点同步已发现的主机标签。
  • 对于 CVE-2026-120495,你运行的是 Pro、Ultimate、Cloud 或 Ultimate MT 版本并启用了 Robotmk 合成监控,而且受监控主机可以发送伪造的代理数据。

第一个漏洞不需要 Kubernetes。能创建规则的用户即使站点没有监控任何集群,也可以添加 Kubernetes 特殊代理规则。第三个漏洞需要为该主机启用自动服务发现,或者由监控管理员手动确认 Robotmk 服务。

系列 受影响版本 修复版本
2.5 2.5.0 至 2.5.0p18 2.5.0p19,2026-11-11 发布
2.4 2.4.0 至 2.4.0p39 2.4.0p40,2026-11-11 发布
2.3 所有 2.3.0 版本 无;已停止支持
3.0 3.0.0b1 尚未发布;包含修复

在每个站点上检查版本,包括远程站点:

omd version

在一个站点内部,监控核心会报告相同的版本:

sudo -u <site> cmk --version

Web 界面在 Help > About 下显示版本。如果不确定有哪些站点,omd sites 会列出站点名称。

如何修复?

安装与你的版本和发行版对应的 2.5.0p19 或 2.4.0p40 软件包,然后更新每个站点。厂商的 werk 页面将这些版本标记为兼容,更新后无需手动操作。

  1. 安装与你的版本对应的软件包,例如 check-mk-raw-2.5.0p19、check-mk-enterprise-2.5.0p19 或对应的 2.4.0p40 软件包。
  2. 更新每个站点,包括远程站点: omd update <site>
  3. 在 Checkmk 设备上,在设备界面中上传 2.5.0p19 或 2.4.0p40 镜像,并在那里运行更新。
  4. 确认结果: omd version
  5. 在每个分布式站点上重复。主机标签漏洞在中心站点修复;Kubernetes 和 Robotmk 漏洞在运行这些检查的站点上修复。

如果无法立即更新,请采取以下措施降低暴露。每项措施只限制一条攻击路径,不能替代补丁。

  1. 从所有非管理角色中移除“Edit rules”权限,并检查这些角色可以访问哪些文件夹。管理员仍然可以利用 CVE-2026-121374,因此该措施只消除了普通监控用户的默认路径。
  2. 不要将中心站点连接到你不控制的远程站点。CVE-2026-118965 没有配置开关;修复只能靠更新。
  3. 对于 CVE-2026-120495,将受监控主机视为不受信任。限制可以添加服务的人员,并对你不管理的主机关闭自动服务发现。当管理员添加其服务时,能够发送代理数据的主机仍然会触达该漏洞。
  4. 将任何 2.3.0 站点迁移到 2.4.0p40 或 2.5.0p19。2.3.0 系列已停止支持,没有修复版本。

根本原因是什么?

三个漏洞有共同的模式。较低权限方控制的值在没有限制的情况下到达命令行或文件路径。站点用户的权限随后将写入变成代码执行。每个入口点不同,因此每个修复也不同。

第一个漏洞位于 Kubernetes 特殊代理中。规则选项“Cluster resource aggregation > Exclude nodes based on their role”收集角色名称。服务器端调用将这些名称作为独立命令行参数放在一个选项之后传给代理:

match params.cluster_resource_aggregation:
    case ("cluster_aggregation_exclude_node_roles", list(excluded_roles)):
        args.append("--cluster-aggregation-exclude-node-roles")
        args.extend(excluded_roles)

代理使用 argparse 解析参数。存在漏洞的解析器用 nargs="+" 声明该选项,因此它会消费后面所有看起来不像选项的标记:

group.add_argument(
    "--cluster-aggregation-exclude-node-roles",
    nargs="+",
    default=["control-plane", "infra"],
    dest="roles",
)

以 --profile 开头的角色值对 argparse 来说不是值,而是一个新选项,下一个角色值会成为它的参数。--profile 选项会将性能分析数据写入文件,并在同一目录写入一个可执行的 Python 启动器,其源码包含性能分析路径:

f'stats = pstats.Stats("{self._profile_file}")\n'

因此,包含双引号和 Python 语法的路径会改变启动器的源码。根据 werk 的评估,规则编辑者可以写入内容受控的可执行 Python 脚本,并以站点用户身份实现代码执行。

第二个漏洞位于主机标签同步中。中心站点向每个远程站点询问其主机的已发现主机标签,然后将返回的内容写入磁盘。存在漏洞的代码在没有任何检查的情况下,将远程站点提供的文件名拼接到标签目录:

def save_updated_host_label_files(updated_host_labels: list[UpdatedHostLabelsEntry]) -> None:
    for file_name, mtime, content in updated_host_labels:
        file_path = cmk.utils.paths.discovered_host_labels_dir / file_name
        store.save_text_to_file(file_path, content)
        os.utime(file_path, (mtime, mtime))

包含 ../ 的文件名会逃出目录,而以其他后缀结尾的文件名会写入站点随后导入或执行的文件。因此,受入侵的远程站点可以在中心站点写入任意文件。

第三个漏洞位于 Robotmk 测试服务中。该服务从代理数据中获取测试用例名称,并用它创建 HTML 日志的文件夹。最终路径没有被验证,因此伪造的测试用例名称会逃出日志目录。日志内容也由用户定义,这使写入在厂商评估中变成代码执行。

如何被利用?

每个漏洞需要不同的起点。除了第三个漏洞需要能够发送代理数据的主机外,其他漏洞都不需要受监控主机本身存在漏洞。

对于 CVE-2026-121374:

  1. 可以编辑规则的用户创建或修改 Kubernetes 特殊代理规则。
  2. 在“Exclude nodes based on their role”中,用户输入 --profile 作为一个角色,并输入一个路径作为下一个值。
  3. 特殊代理运行时,argparse 将 --profile 读作选项,将路径读作其参数。
  4. 代理将性能分析数据和启动器脚本写入所选路径。启动器在 Python 字符串中包含该路径。
  5. 用引号和 Python 代码构造的路径会改变启动器的源码。厂商将得到的可执行脚本视为以站点用户身份执行代码。

对于 CVE-2026-118965:

  1. 攻击者控制或入侵分布式设置中的一个远程站点。
  2. 远程站点用一个包含 ../ 的文件名响应中心站点的主机标签请求。
  3. 中心站点的同步将提供的内容写入解析后的路径。
  4. 攻击者选择一个站点用户会导入或执行的路径,从而在中心站点实现代码执行。

对于 CVE-2026-120495:

  1. 攻击者可以为受监控主机添加代理数据,例如通过恶意代理插件或 spool 文件。werk 指出这通常需要该主机上的 root 权限。
  2. 伪造的数据定义一个逃出 HTML 日志目录的 Robotmk 测试用例名称。
  3. 站点将内容由攻击者控制的 HTML 日志写入解析后的路径。
  4. 厂商将结果评定为以站点用户身份执行代码。

攻击如何展开?

三个不同的输入到达同一个结果:以 Checkmk 站点用户身份写入文件,厂商将其视为代码执行。

flowchart LR A["规则编辑者设置
被排除的节点角色"] --> B["角色被读作
--profile 选项"] C["恶意远程站点
返回标签文件名"] --> D["文件名在未检查路径的
情况下拼接到
标签目录"] E["受入侵主机发送
Robotmk 测试名称"] --> F["测试名称在未检查路径的
情况下用作
日志文件夹"] B --> G["以站点用户身份
写入文件"] D --> G F --> G G --> H["以站点用户身份
执行代码"] style D fill:#f8d7da style F fill:#f8d7da

攻击者能做什么?

达到代码执行的攻击者会以 Checkmk 站点用户身份运行命令。该账户可以读取监控配置、Checkmk 用于连接受监控设备的凭据以及站点文件。条件因漏洞而异。

  • CVE-2026-121374:攻击者需要一个可以在至少一个文件夹中编辑规则的用户。站点不需要监控 Kubernetes,因为攻击者会创建规则。结果是站点用户身份下的代码执行。
  • CVE-2026-118965:攻击者需要控制分布式设置中的一个远程站点。结果是中心站点上的任意文件写入以及中心站点用户身份下的代码执行。
  • CVE-2026-120495:攻击者需要为受监控主机提供伪造的代理数据,werk 指出这通常需要该主机上的 root 权限,并且需要自动服务发现或管理员添加 Robotmk 服务。结果是站点用户身份下的代码执行。

站点用户不是 Checkmk 服务器上的 root。但它仍然可以读取监控数据和为受监控系统存储的凭据,因此请将入侵视为这些系统也已暴露。

为什么修复有效?

修复消除了值与选项之间的歧义,并限制了站点写入的路径。

Kubernetes 修复将每个角色作为带有附加值的独立选项传递,解析器现在逐个追加它们:

     match params.cluster_resource_aggregation:
         case None:
-            args.extend(["--cluster-aggregation-exclude-node-roles", "control-plane", "infra"])
+            args.extend(
+                f"--cluster-aggregation-exclude-node-role={role}"
+                for role in ("control-plane", "infra")
+            )
         case ("cluster_aggregation_include_all_nodes", None):
             args.append("--cluster-aggregation-include-all-nodes")
         case ("cluster_aggregation_exclude_node_roles", list(excluded_roles)):
-            args.append("--cluster-aggregation-exclude-node-roles")
-            args.extend(excluded_roles)
+            args.extend(
+                f"--cluster-aggregation-exclude-node-role={role}" for role in excluded_roles
+            )
     group.add_argument(
-        "--cluster-aggregation-exclude-node-roles",
-        nargs="+",
-        default=["control-plane", "infra"],
+        "--cluster-aggregation-exclude-node-role",
+        action="append",
+        default=None,
         dest="roles",
+        metavar="ROLE",
     )

角色现在是 --cluster-aggregation-exclude-node-role=<role> 标记的一部分,因此 argparse 无法将其读作独立选项。代理还将 --profile 限制在 ~/tmp/check_mk/debug,并将路径作为 Python 字面量写入启动器:

+def _profile_file(filename: str) -> Path:
+    path = Path(filename).resolve()
+    allowed = (Path.home() / _PROFILE_DIR).resolve()
+    if not path.is_relative_to(allowed):
+        raise argparse.ArgumentTypeError(f"Profiles can only be stored in {allowed}")
+    return path
-                f'stats = pstats.Stats("{self._profile_file}")\n'
+                f"stats = pstats.Stats({str(self._profile_file)!r})\n"

主机标签修复会解析目标,并要求它留在标签目录下、带有 .mk 后缀、使用有效主机名作为词干:

+def _make_secure_path(base: Path, leaf: str) -> Path:
+    path = Path(base).resolve()
+    resolved = (path / leaf).resolve()
+    if not resolved.is_relative_to(path):
+        raise ValueError(f"Path {resolved} is not relative to {path}")
+    if resolved.suffix != ".mk":
+        raise ValueError(f"Path {resolved} does not have .mk suffix")
+    HostName(resolved.stem)  # would raise if validation fails
+    return resolved
+
+
 def save_updated_host_label_files(updated_host_labels: list[UpdatedHostLabelsEntry]) -> None:
     for file_name, mtime, content in updated_host_labels:
-        file_path = cmk.utils.paths.discovered_host_labels_dir / file_name
+        file_path = _make_secure_path(cmk.utils.paths.discovered_host_labels_dir, file_name)

Robotmk 变更将生成的日志限制在 ~/var/robotmk/html_logs 内,当日志会落到该目录外时返回 UNKNOWN 服务状态。Robotmk 变更随同一个修复版本发布,其 werk 是新路径规则的公开记录。

如何检查是否已遭入侵?

Checkmk 没有为这些漏洞发布入侵指标。失败的尝试,或者写入了站点从未执行的文件,可能除了文件本身之外不留下任何痕迹。检查漏洞涉及的三个位置。

  1. 检查审计日志中是否有添加 Kubernetes 特殊代理规则或修改“Exclude nodes based on their role”的规则变更。在 Web 界面中打开 Setup > General > Audit log,并按 Kubernetes 规则集筛选。
  2. 查找站点调试目录中的意外文件: sudo -u <site> find ~/tmp/check_mk/debug -type f -name '*.py' 2>/dev/null
  3. 列出已发现的主机标签文件,确认每个名称都是你监控的主机: sudo -u <site> ls -la ~/var/check_mk/discovered_host_labels
  4. 在 Pro、Ultimate、Cloud 和 Ultimate MT 站点上,查找预期目录之外的 HTML 日志: sudo -u <site> find ~/var/robotmk/html_logs -type f 2>/dev/null 包含 .. 的路径不能作为字面名称存在,因此请检查父目录不是你认识的测试用例文件夹的文件。

命中是应调查的线索,不是利用的证明。只有当攻击者的规则变更被记录且日志随后未被修改时,审计日志才有帮助。

时间线

  • 2026-10-29:CVE-2026-118965 的修复提交到 Checkmk 仓库。
  • 2026-11-02:CVE-2026-120495 的修复记录在其 werk 中。
  • 2026-11-03:CVE-2026-121374 的修复提交到 Checkmk 仓库。
  • 2026-11-11:Checkmk 发布 2.5.0p19 和 2.4.0p40,并发布三个 CVE 记录。

修复在 2026 年 10 月 29 日至 11 月 11 日之间落地,修复版本结束了 13 天的窗口
图 1:从第一个修复提交到修复版本。来源:Checkmk werk 和发布说明,2026 年 11 月 11 日检查

常见问题

这会影响 Community 版本吗?

CVE-2026-121374 和 CVE-2026-118965 会影响所有版本。CVE-2026-120495 只影响 Pro、Ultimate、Cloud 和 Ultimate MT 版本,因为 Robotmk 合成监控不属于 Community 版本。修复后的 2.5.0p19 和 2.4.0p40 软件包适用于所有版本。

我不监控 Kubernetes,还会受第一个漏洞影响吗?

如果用户可以编辑规则,是的。攻击者会创建 Kubernetes 特殊代理规则,因此站点不需要监控集群。在更新之前,请从非管理角色中移除规则编辑权限。

2.3.0 版本修复了吗?

没有。2.3.0 系列已停止支持,三个 werk 都将其列为受影响且没有修复版本。请将这些站点迁移到 2.4.0p40 或 2.5.0p19。

这些漏洞在实际环境中被利用了吗?

截至 2026 年 11 月 11 日没有已知利用,三个 CVE 都不在 CISA 的 KEV 目录中。Kubernetes 漏洞是在内部审查中发现的,主机标签漏洞通过厂商的安全披露流程报告。情况可能变化,因此在计划长期延迟之前请检查 KEV 目录。

升级后需要修改配置吗?

不需要。三个 werk 都标记为兼容且无需手动操作。Kubernetes 代理接受新的按角色选项,主机标签和 Robotmk 检查会自动应用新的路径规则。

如何知道我正在运行哪个版本?

omd version 显示每个站点的版本,服务器上的软件包名称会标明版本,例如 Community 的 check-mk-raw 或 Enterprise 的 check-mk-enterprise。Web 界面在 Help > About 下显示版本。

使用 Ostorlab 发现暴露的 Checkmk 服务器

使用 Ostorlab Attack Surface Discovery 清点你拥有的面向互联网的主机和 Web 界面,从而了解哪些 Checkmk 站点可以访问、需要优先更新。它映射暴露的服务,并不检测此 CVE。

参考文献

  • Checkmk werk 17994,“Kubernetes: Arbitrary file write and code execution via excluded node roles”,CVE-2026-121374,日期 2026-11-03:https://checkmk.com/werk/17994(2026 年 11 月 11 日检查)
  • Checkmk werk 22120,“Code execution through compromised remote site”,CVE-2026-118965,日期 2026-10-29:https://checkmk.com/werk/22120(2026 年 11 月 11 日检查)
  • Checkmk werk 22624,“Code execution through Robotmk HTML log test service”,CVE-2026-120495,日期 2026-11-02:https://checkmk.com/werk/22624(2026 年 11 月 11 日检查)
  • CVE-2026-121374 记录,Checkmk CNA,2026-11-11 发布:https://www.cve.org/CVERecord?id=CVE-2026-121374(2026 年 11 月 11 日检查)
  • CVE-2026-118965 记录,Checkmk CNA,2026-11-11 发布:https://www.cve.org/CVERecord?id=CVE-2026-118965(2026 年 11 月 11 日检查)
  • CVE-2026-120495 记录,Checkmk CNA,2026-11-11 发布:https://www.cve.org/CVERecord?id=CVE-2026-120495(2026 年 11 月 11 日检查)
  • CVE-2026-121374 的修复提交 5a2c448efa,2026-11-03:https://github.com/Checkmk/checkmk/commit/5a2c448efafb1e3f2dab75babdecb5f99d0a0618(2026 年 11 月 11 日检查)
  • CVE-2026-118965 的修复提交 8efcf83a15,2026-10-29:https://github.com/Checkmk/checkmk/commit/8efcf83a153b201ce640a6c1da9de9c52d9c3650(2026 年 11 月 11 日检查)
  • CVE-2026-120495 的修复提交 4ba4c9f638,2026-11-03:https://github.com/Checkmk/checkmk/commit/4ba4c9f638cf83509970e78468f79bf846327d7b(2026 年 11 月 11 日检查)
  • Checkmk 2.5.0p19 发布说明索引,2026 年 11 月 11 日:https://checkmk.com/werks?version=2.5.0p19(2026 年 11 月 11 日检查)
  • Checkmk 2.4.0p40 发布说明索引,2026 年 11 月 11 日:https://checkmk.com/werks?version=2.4.0p40(2026 年 11 月 11 日检查)
  • CISA 的 Known Exploited Vulnerabilities 目录,版本 2026.11.10,未列出这三个 CVE:https://www.cisa.gov/known-exploited-vulnerabilities-catalog(2026 年 11 月 11 日检查)
  • 图 1,修复到发布的时间线:日期来自参考文献所列的三个 werk 和两个发布索引,2026 年 11 月 11 日检查。