2025 年 5 月,一个被称为 IngressNightmare 的关键安全漏洞(CVE-2025-1974)被公开披露,该漏洞影响了广泛部署在云原生基础架构中的 Kubernetes ingress-nginx 控制器。该漏洞允许未经身份验证的攻击者向 NGINX 注入任意配置,可能导致未经授权的 RCE(远程代码执行)和整个集群崩溃。
作为OPSWAT 研究金计划的一部分,我们的研究员进行了深入的技术分析,以更好地了解其根本原因、开发路径以及围绕这一严重问题的缓解策略。
CVE-2025-1974 概览
CVE-2025-1974 是在 1.11.4 及以下版本(特别是 1.12.0)的 ingress-nginx 中发现的关键模板注入漏洞。拥有 Kubernetes 集群节点级访问权限的攻击者可利用此漏洞,通过 ingress-nginx 控制器使用 RCE 执行任意代码。
Kubernetes 安全响应委员会将此漏洞的 CVSS v3.1 分值定为 9.8(严重程度):
分析的主要内容
Kubernetes 概述
Kubernetes(K8s)是一个开源平台,用于自动化部署、扩展和运营管理容器化应用程序。Kubernetes 集群通常由多台机器组成,其中既包括物理硬件,也包括虚拟机,它们协同工作,提供高度可用、可扩展和可管理的应用环境。
NGINX 入口控制器
NGINX 入口控制器(ingress-nginx)是建立在 NGINX Web 服务器之上的开源入口控制器。它在 Kubernetes 集群中运行,主要起反向代理和负载平衡器的作用。该控制器解释用户定义的 Ingress 资源,并将其转化为可操作的 NGINX 配置,以将流量路由到集群中。
入学审查及其作用
Ingress-nginx 使用名为 AdmissionReview 的 webhook 服务与 Kubernetes 集成。这项服务对于处理本地 Kubernetes Ingress 对象并将其转化为经过验证且语法正确的 NGINX 配置至关重要。虽然 AdmissionReview 可以确保配置的准确性,但它独立于 ingress-nginx 控制器运行,通常缺乏严格的身份验证控制。缺乏严格的身份验证是导致 CVE-2025-1974 被利用的关键因素。
漏洞利用和技术分析
利用机制
CVE-2025-1974 漏洞利用的核心是恶意请求。攻击者向 AdmissionReview 网络钩子发出恶意请求,迫使 NGINX 在运行时动态加载共享库。根据这一机制,我们的研究人员分析了 AdmissionReview 网络钩子和 NGINX 工作流,以了解这一利用路径。
模板注入漏洞
在 AdmissionReview 网络钩子上,当处理传入请求时,CheckIngress函数会将 Kubernetes Ingress 对象转换为有效的 NGINX 配置文件。流程如下
- 每个配置都会被解析并传递给generateTemplate,以便根据预定义的 NGINX 模板进行格式化。
- 随后,testTemplate会根据底层 NGINX 二进制验证生成的配置。
所有 NGINX 配置都基于 ingress-nginx 源代码中 nginx.tmpl 文件的预定义模板:
在生成模板(generateTemplate)函数中,配置将按以下代码片段进行处理:
然而,输入验证和消毒并不充分。具体来说,Ingress 对象的uid字段被直接插入 NGINX 配置模板,从而创建了一个注入点。攻击者可通过提供精心制作的输入(如uid="1234#;\n\n}\n}\n injection_value")来利用这一点。
这种恶意输入允许向 NGINX 模板注入全局范围,使攻击者能够触发任意 NGINX 指令,并可能实现 RCE。
从模板注入到远程代码执行
testTemplate() 函数说明
在generateTemplate函数生成 NGINX 配置后,testTemplate函数会创建一个临时配置文件,并使用nginx -c {config_file} 命令运行 NGINX 库。-t.这将迫使 NGINX 二进制文件解析并验证配置。
要利用这个漏洞,攻击者需要确定一个能够执行恶意代码的指令。最初,我们的研究人员发现load_module指令可能有用,因为该指令允许 NGINX 加载外部插件。但是,只有在配置解析的早期阶段才允许使用该指令,这与我们的注入点不符。
为了解决这一难题,我们继续深入研究,最终发现了ssl_engine指令,其描述为 "在配置测试过程中,该模块可能会被 OpenSSL 动态加载"。这引起了我们对动态加载模块功能的好奇,因此有必要进行更深入的研究。
了解 ssl_engine 指令
为了深入了解 NGINX 如何处理ssl_engine指令,并确定 NGINX 允许通过该指令动态加载其他模块的条件,我们研究了 NGINX 的源代码。
启动时,NGINX会加载初始状态,然后逐行解析配置文件。每条指令都由nginx_command_t结构处理,其中ssl_engine指令直接调用ngx_openssl_commands。
在分析ngx_openssl_commands函数时,我们的研究人员发现它依赖于 OpenSSL 支持,特别是用于硬件加速 SSL 模块的ENGINE_by_id函数。
在分析ENGINE_by_id函数时,我们发现它可以动态加载共享库。此外,如果库在编译时使用了__attribute__((constructor))扩展,相关函数就可以在加载时立即执行。这表明利用ssl_engine指令,攻击者可以在主机上加载任意共享库,从而可能导致RCE。
瞄准共享图书馆和攻击策略
为了可靠地促进代码执行,下一步需要确定一个共享库。与依赖外部库相比,NGINX 自身的行为提供了一种更可行、更可控的方法:客户端主体缓冲机制。该功能使 NGINX 能够将大量传入请求卸载到临时文件中,从而为基于可预测文件处理行为的利用提供了机会。
默认情况下,当传入请求超过 8KB 时,NGINX 会将请求正文写入位于 /tmp/nginx/client-body 的临时文件,文件名格式为 cfg-{random_value}。这些临时文件最多可在接收到的成功信息块之间保留 60 秒。
将部分请求正文写入临时文件后,NGINX 会推迟删除,直到收到整个正文。如果请求仍不完整,且在长达 60 秒的时间内未收到任何数据,文件最终会被清除。但是,攻击者可以通过故意扣留最后一块数据来保持临时文件的使用,使其成为可利用的漏洞。
虽然上传的文件内容可以控制,但由于文件名是随机的,因此很难在文件系统中找到它。存储路径可以使用client_body_temp_path 进行配置,但文件名是在运行时随机生成的,因此无法预测。这种随机性极大地阻碍了目标访问,即使是通过暴力手段。为了克服这一问题,研究小组利用了 Linux 操作系统固有的行为。请看下面的例子:
This code opens a file and keeps it in an active state, closely mimicking the behavior of NGINX's client body buffer mechanism. Using /proc/{pid}/fd directory, attackers can find symbolic links created by the Linux kernel that map open file descriptors to their corresponding file paths. This route allows attackers to reduce the brute-force space to only two variables: the process ID (pid) and the file descriptor (fd).
模拟剥削
根据上述分析,在 Ingress-NGINX pod 中利用 RCE 的实用方法是
- 使用 NGINX 的客户端主体缓冲机制上传恶意共享库,将其临时存储在文件系统中。
- 使用模板注入启动暴力尝试,迫使 NGINX 通过易受攻击的指令加载先前上传的共享库。
制作包含共享库的有效载荷
为确保在加载时执行代码,恶意共享库中定义了一个带有构造函数扩展的入口点函数。该函数在 NGINX 加载时执行,旨在建立与远程主机的反向外壳连接。
编译后,生成的共享库大小刚好超过 8KB,因此 NGINX 可以对其进行缓冲,而无需额外填充。
然后,我们的研究人员用夸大的Content-Length值(如 1MB)伪造了一个请求,以引入大小不匹配。这导致 NGINX 对整个正文进行缓冲,而不是立即处理,从而确保共享对象被写入可预测的位置。
通过注入触发共享库
共享库就位后,我们接下来使用易受攻击的uid字段在 NGINX 配置中注入了一个恶意指令。该指令包括指向缓冲文件路径的ssl_engine:
成功的 RCE 要求ssl_engine指令引用缓冲文件的正确路径。这可以通过自动暴力脚本来实现,该脚本会系统地遍历进程 ID 和文件描述符的可能组合,以识别指向缓冲共享对象的有效符号链接。
以下是生成的 NGINX 模板示例,该模板触发了漏洞利用。
成功利用后,攻击者可以在 ingress-nginx pod 的上下文中获得 shell 访问权限,默认情况下,该 pod 可以访问敏感的 Kubernetes 集群机密。
缓解和补救
为了有效降低与 CVE-2025-1974 相关的风险,企业需要一种能对其开源组件提供可见性和控制的解决方案。
OPSWAT SBOM 是MetaDefender® 平台中的一项基础技术,通过提供使用中的所有软件组件、库、Docker 容器和依赖项的清单来满足这一需求。它使企业能够主动跟踪、保护和更新其组件。
在上面的示例中,MetaDefender Core™ 中的SBOM 技术扫描了包含 CVE-2025-1974 漏洞的 nginx-ingress-controller 软件包。系统自动将该问题标记为 "危急"(Critical),并提供可用修复版本的指导,使团队能够在漏洞被利用之前快速确定优先级并修补漏洞。
OPSWAT SBOM 可在MetaDefender Core 和MetaDefender Software Supply Chain™ 中使用,使安全团队能够更快地识别漏洞并采取行动。借助OPSWAT SBOM,安全团队可以
- 快速定位易受攻击的组件--立即识别受反序列化攻击影响的开源组件。这可确保迅速采取行动,修补或替换易受攻击的库。
- 确保主动打补丁和更新--通过OPSWAT SBOM 持续监控开源组件,提前发现反序列化漏洞。OPSWAT SBOM 可检测过时或不安全的组件,从而实现及时更新,减少遭受攻击的风险。
- 保持合规性和报告- 随着监管框架对软件供应链透明度的要求越来越高,OPSWAT SBOM 可帮助企业满足合规性要求。