漏洞简介

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 端点不会对外暴露