IngressNightmare之CVE-2025-1974漏洞复现
Ingress-nginx 恶意配置文件RCE
漏洞简介
Ingress Nginx Controller 是 K8s 上最受欢迎的 Ingress 控制器之一,有权访问 ingress-nginx 准入控制器 webhook 的攻击者可以创建恶意的 ingress-nginx Ingress 配置,从而导致 RCE
漏洞原因
当Ingress Nginx Controller处理传入的 AdmissionReview请求时,它会根据模板文件和提供的 Ingress 对象生成一个临时 NGINX 配置文件。然后,它使用 nginx -t命令测试临时配置文件的有效性。
问题关键点有三个,谁可以发送AdmissionReview请求?,如何注入恶意NGINX配置文件?,如何利用nginx -t 命令执行rce?
对于第一个问题,通常,只有 Kubernetes API 服务器应该发送这些 AdmissionReview 请求。但是,由于 Admission Controller 缺少身份验证,因此具有最小网络访问权限的攻击者可以从集群内的任何 Pod 构建并发送任意 AdmissionReview 请求。
第二个问题,CVE-2025-1974漏洞是IngressNightmare漏洞集群中的一个,与其同时爆出的CVE-2025-24514,CVE-2025-1097,CVE-2025-1098皆为远程NGINX配置注入,可利用这三个漏洞实现注入任意 NGINX 配置指令。
第三个问题,Ingress Nginx Controller 中有许多可用的指令,ssl_engine 指令是 OpenSSL 模块的一部分,这个指令可以在配置文件中的任何位置使用,以在 NGINX 配置测试阶段加载任意库文件。此时出现第四个问题,如何上传恶意共享库文件?
如果 HTTP 请求正文大小大于特定阈值(默认为8KB)时,NGINX 有时会将请求体保存到临时文件中,将请求中的标头设置为大于实际内容大小。NGINX 会一直等待发送更多数据,这会导致进程挂起,让文件描述符打开的时间更长,通过遍历爆破 PID 和 FD 编号,找到文件描述符,对恶意共享库进行加载。
漏洞代码
ingress-nginx/internal/ingress/controller/controller.go
content, err := n.generateTemplate(cfg, *pcfg)
if err != nil {
n.metricCollector.IncCheckErrorCount(ing.ObjectMeta.Namespace, ing.Name)
return err
}
err = n.testTemplate(content)
if err != nil {
n.metricCollector.IncCheckErrorCount(ing.ObjectMeta.Namespace, ing.Name)
return err
}generateTemplate函数生成cfg文件,testTemplate函数进行配置测试
testTemplate函数如下
func (n *NGINXController) testTemplate(cfg []byte) error {
if len(cfg) == 0 {
return fmt.Errorf("invalid NGINX configuration (empty)")
}
tmpfile, err := os.CreateTemp(filepath.Join(os.TempDir(), "nginx"), tempNginxPattern)
if err != nil {
return err
}
defer tmpfile.Close()
err = os.WriteFile(tmpfile.Name(), cfg, file.ReadWriteByUser)
if err != nil {
return err
}
out, err := n.command.Test(tmpfile.Name())
if err != nil {
// this error is different from the rest because it must be clear why nginx is not working
oe := fmt.Sprintf(`
-------------------------------------------------------------------------------
Error: %v
%v
-------------------------------------------------------------------------------
`, err, string(out))
return errors.New(oe)
}
os.Remove(tmpfile.Name())
return nil
}在testTemplate函数调用Test函数,Test函数代码如下
func (nc NginxCommand) Test(cfg string) ([]byte, error) {
//nolint:gosec // Ignore G204 error
return exec.Command(nc.Binary, "-c", cfg, "-t").CombinedOutput()
}漏洞复现
使用minikube搭建环境
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube启动minickube
minikube start
安装受漏洞影响版本的ingress-nignx
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.11.2/deploy/static/provider/cloud/deploy.yaml
#下面两条命令用于换源
sed -i 's#registry.k8s.io/ingress-nginx/controller:v1.11.2@sha256:d5f8217feeac4887cb1ed21f27c2674e58be06bd8f5184cacea2a69abaf78dce#registry.aliyuncs.com/google_containers/nginx-ingress-controller:v1.11.2#g' deploy.yaml
sed -i 's#registry.k8s.io/ingress-nginx/kube-webhook-certgen:v1.4.3@sha256:a320a50cc91bd15fd2d6fa6de58bd98c1bd64b9a6f926ce23a600d87043455a3#registry.aliyuncs.com/google_containers/kube-webhook-certgen:v1.4.3#g' deploy.yaml
# 安装
kubectl apply -f deploy.yaml一般情况下启动的validating webhook监听在8443端口 ,用putforward命令进行端口转发
kubectl port-forward -n ingress-nginx ingress-nginx-controller-76c86b6bbd-s86qn 2333:8443
使用网上的Poc进行验证
gir clone https://github.com/sandumjacob/IngressNightmare-POCs
cd ./CVE-2025-1974
curl --insecure -v -H "Content-Type: application/json" --data @poc.json https://localhost:2333/123查看日志
kubectl logs ingress-nginx-controller-76c86b6bbd-s86qn -n ingress-nginx
出现以下语句,说明验证了上传的nginx配置,即存在漏洞
I0326 02:53:15.823881 7 main.go:107] "successfully validated configuration, accepting" ingress="/"
进行深一步利用需搭配IngressNightmare的其余漏洞,攻击分三步实现RCE:上传恶意.so文件至Pod临时存储;通过Content-Length标头维持文件描述符;注入ssl_engine指令加载恶意库。
影响范围
Ingress NGINX Controller 版本< 1.12.1
Ingress NGINX Controller 版本< 1.11.5
Ingress NGINX Controller 版本< 1.10.7
修复建议
这些漏洞已在 Ingress NGINX Controller 的 1.12.1、1.11.5 和 1.10.7 版本中得到修复。建议用户尽快更新到最新版本,并确保准入 Webhook 端点不会对外暴露