Ingress NGINX 中的9.8级危急未授权远程代码执行漏洞
超过40%的云环境容易受到可能导致集群完全接管的RCE攻击。
Wiz研究团队发现了CVE-2025-1097、CVE-2025-1098、CVE-2025-24514和CVE-2025-1974,这是一系列在Kubernetes的Ingress NGINX Controller中的未授权远程代码执行漏洞,被称为#IngressNightmare。攻击者利用这些漏洞可以未经授权访问Kubernetes集群中所有命名空间中存储的所有密钥,从而可能导致集群被接管。
这个攻击向量的CVSS v3.1基础评分为9.8。
我们要感谢Ingress-NGINX维护者,特别是Marco Ebert在解决IngressNightmare漏洞方面的帮助。我们的团队与Kubernetes维护者和安全团队密切合作,确保在公开披露之前完全消除这个攻击面。Kubernetes的博客可以在这里找到,Amazon和Google Cloud也发布了他们自己的建议。
什么是Kubernetes的Ingress NGINX Controller?
Ingress NGINX Controller是Kubernetes最流行的ingress控制器之一,也是核心Kubernetes项目,在GitHub上有超过18,000颗星。使用Ingress-NGINX是对外暴露Kubernetes应用程序最常见的方法之一。作为入口控制器,它的工作是接受传入流量并根据一组规则将其路由到相关的Kubernetes服务,而服务又将流量转发到适当的Pod。具体来说,Ingress NGINX Controller基于流行的NGINX反向代理。
根据我们的研究,超过41%的面向互联网的集群正在运行Ingress-NGINX。
漏洞详情
Ingress NGINX在其pod中部署了一个准入控制器,用于在部署之前验证传入的ingress对象。默认情况下,准入控制器无需认证即可通过网络访问,这使其成为极具吸引力的攻击目标。
当Ingress-NGINX准入控制器处理传入的ingress对象时,它会从中构建NGINX配置,然后使用NGINX二进制文件验证它。我们的团队在这个阶段发现了一个漏洞,通过直接向准入控制器发送恶意ingress对象,可以通过网络注入任意NGINX配置。
在配置验证阶段,注入的NGINX配置会导致NGINX验证器执行代码,允许在Ingress NGINX Controller的pod上进行远程代码执行(RCE)。
缓解和检测
首先,确定您的集群是否使用ingress-nginx。在大多数情况下,您可以通过运行以下命令进行检查:
kubectl get pods --all-namespaces --selector app.kubernetes.io/name=ingress-nginx
这个漏洞在Ingress NGINX Controller 版本1.12.1和1.11.5中已修复。我们强烈建议集群管理员:
-
• 更新到最新版本的Ingress NGINX Controller -
• 确保准入webhook端点不对外暴露 -
• 您可以使用Nuclei模板检查是否暴露了Ingress-NGINX准入控制器
如果您无法立即升级,请考虑以下缓解措施:
-
• 实施严格的网络策略,使得只有Kubernetes API Server可以访问准入控制器 -
• 如果您暂时无法升级,临时禁用Ingress-NGINX的准入控制器组件
发现过程和技术细节
我们如何发现IngressNightmare?
研究动机
Kubernetes准入控制器在Kubernetes环境中呈现出一个有趣且经常被忽视的攻击面。它们由Kubernetes API服务器触发,用于在请求被处理之前审查并可能修改或阻止请求(AdmissionReview)。准入控制器通常在集群内运行时具有相对较高的权限,且往往不需要身份验证,本质上功能类似于Web服务器,在集群中引入了额外的内部网络可访问端点。这种架构允许攻击者从网络中的任何pod直接访问它们,显著增加了攻击面。
Ingress NGINX Controller背景
Ingress NGINX Controller是一个使用NGINX作为反向代理和负载均衡器的ingress实现。它是最受欢迎的ingress之一,也是核心Kubernetes项目。
为了在Kubernetes和NGINX配置(这是一个非Kubernetes原生技术)之间搭建桥梁,控制器试图将Kubernetes Ingress对象转换为NGINX配置。为确保NGINX服务器的稳定性,控制器使用验证准入webhook在应用配置之前验证最终配置。
远程NGINX配置注入
nginx -t
命令测试临时配置文件的有效性。CVE-2025-1974 - NGINX配置代码执行
最初我们尝试使用load_module
指令,它可以从文件系统加载共享库。但是,它只能在NGINX配置的开始处使用,所以当注入时,load_module
会失败并显示以下错误消息:
在Ingress NGINX Controller中有许多可用的指令,因为他们的NGINX实例编译时包含了许多额外模块。我们发现ssl_engine
指令(OpenSSL模块的一部分)也可以加载共享库。这个行为是未记录的。与load_module
不同,这个指令可以在配置文件中的任何位置使用,所以它适合我们的注入约束。
使用NGINX客户端主体缓冲区上传共享库
除了nginx -t
和准入控制器webhook外,pod还运行着NGINX实例本身,监听80或443端口。
在处理请求时,NGINX有时会将请求主体保存到临时文件中(客户端主体缓冲)。当HTTP请求主体大小超过某个阈值(默认为8KB)时就会发生这种情况。这意味着理论上我们应该能够发送一个大型(>8KB)的HTTP请求,将我们的payload以共享库的形式作为请求主体,NGINX会将其临时保存到pod的文件系统中。
从配置注入到RCE
完整的漏洞利用过程如下:
-
1. 通过滥用NGINX的客户端主体缓冲特性,将我们的payload以共享库形式上传到pod -
2. 向Ingress NGINX Controller的准入控制器发送包含我们的指令注入的AdmissionReview请求 -
3. 我们注入的是 ssl_engine
指令,这将导致NGINX加载指定的文件作为共享库 -
4. 我们指定payload的ProcFS文件描述符路径 -
5. 如果一切顺利,我们的共享库就会被加载,从而实现远程代码执行
结论
我们仅仅触及了准入控制器安全审查的表面。最初,我们对在后台使用如此大的代码库感到惊讶。我们认为这个攻击面应该以更好的方式被限制:移除集群内pod的访问权限,永远不要公开暴露这个接口。我们也对缺乏最小权限设计感到惊讶,因为漏洞最终获得了控制集群的权限。
负责任的披露时间线
2024年12月31日 - Wiz研究团队向Kubernetes报告了CVE-2025-1974和CVE-2025-24514。
2025年1月2日 - Wiz研究团队向Kubernetes报告了CVE-2025-1097。
2025年1月3日 - Kubernetes确认收到报告。
2025年1月9日 - Kubernetes提出了CVE-2025-1097的修复方案。
2025年1月10日 - Wiz研究团队报告了对CVE-2025-1097提议修复方案的绕过。
2025年1月12日 - Kubernetes提出了CVE-2025-1974的修复方案。
2025年1月16日 - Wiz研究团队报告了对CVE-2025-1974提议修复方案的绕过。
2025年1月20日 - Kubernetes提出了CVE-2025-24513的修复方案。
2025年1月21日 - Wiz研究团队报告了对CVE-2025-24513提议修复方案的绕过。
2025年1月21日 - Wiz研究团队向Kubernetes报告了CVE-2025-1098。
2025年2月7日 - Kubernetes发布了注入漏洞的内部补丁:CVE-2025-1098、CVE-2025-1097和CVE-2025-24514。
2025年2月20日 - Kubernetes通知Wiz研究团队他们已从准入控制器中移除了NGINX配置验证,解决了CVE-2025-1974。
2025年3月10日 - Kubernetes发送了关于Wiz研究团队报告的五个漏洞的禁令通知。
2025年3月24日 - 公开披露。
原文始发于微信公众号(网安守护):IngressNightmare:9.8 Ingress NGINX 中存在关键的未经身份验证的远程代码执行漏洞
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论