Goal Reached Thanks to every supporter — we hit 100%!

Goal: 1000 CNY · Raised: 1000 CNY

100.0%

CVE-2025-1974 PoC — ingress-nginx admission controller RCE escalation

Source
Associated Vulnerability
Title:ingress-nginx admission controller RCE escalation (CVE-2025-1974)
Description:A security issue was discovered in Kubernetes where under certain conditions, an unauthenticated attacker with access to the pod network can achieve arbitrary code execution in the context of the ingress-nginx controller. This can lead to disclosure of Secrets accessible to the controller. (Note that in the default installation, the controller can access all Secrets cluster-wide.)
Description
My view on IngressNightmare vulnerability (CVE-2025-1974)
Readme
# IngressNightterror (CVE-2025-1974)

<p align="center">
<img src="logo.png" width="450"/>
</p>

### Overview

This repository is my research on IngressNightmare vulnerability. It includes a vulnerable Ingress deploy files, exploit itself and shared object payload.

### CVE

The list of CVE indexes:
- [CVE-2025-1974](https://nvd.nist.gov/vuln/detail/CVE-2025-1974) - Root vulnerability
- [CVE-2025-24514](https://nvd.nist.gov/vuln/detail/CVE-2025-24514) - `auth-url` annotation injection
- [CVE-2025-1097](https://nvd.nist.gov/vuln/detail/CVE-2025-1097) -  `auth-tls-match-cn` annotation injection
- [CVE-2025-1098](https://nvd.nist.gov/vuln/detail/CVE-2025-1098) - image UID abuse

### References

Just some refs:
- [Original WIZ Research post](https://www.wiz.io/blog/ingress-nginx-kubernetes-vulnerabilities)
- [Kubernetes github issue](https://github.com/kubernetes/kubernetes/issues/131009)
- [Kubernetes blog post](https://kubernetes.io/blog/2025/03/24/ingress-nginx-CVE-2025-1974)
- [Amazon AWS bulletin](https://aws.amazon.com/security/security-bulletins/AWS-2025-006/)
- [Google clound bulletin](https://cloud.google.com/support/bulletins/index#gcp-2025-013)

## Root cause

The root of this vulnerability lies in the lack of proper input sanitization. When you send an `AdmissionReview` request, it creates a temporary NGINX configuration that is later tested for validity using the [`nginx -t`](https://linux.die.net/man/8/nginx) command. See the [source code](https://github.com/kubernetes/ingress-nginx/blob/8c1ecd7655bd052a26e64d3361dede3096cd80c6/internal/ingress/controller/controller.go#L425) with the bug mitigated.

The ability to control the content of the configuration being tested allows us to utilize a wide range of config fields to inject malformed config:
* `auth-url` - goes without proper sanitization, allowing us to add a `#` and `\n`. We will use this injection point.
* `auth-tls-match-cn` - only requires the field to start with `CN=` and be a valid regexp.
* `ing.UID` - the UID goes into the config as-is.

The fact that the NGINX config is only tested slightly reduces the number of directives we can use. One of the directives that is left is [`ssl_engine`](https://nginx.org/en/docs/ngx_core_module.html#ssl_engine), which allows us to load shared libraries. This is a nice entry point. But how can we put our `.so` file into the pod filesystem?

The clever folks at WIZ came up with the idea of sending a request with our `.so` object as the body, and if it's big enough, NGINX saves it to a file in procfs! We can also adjust the `Content-Length`, making NGINX wait for more data, causing it to keep the file in procfs for some time. The actual PID and FD number will be guessed.

For more information, read the original analysis [article](https://www.wiz.io/blog/ingress-nginx-kubernetes-vulnerabilities) by the WIZ research team.

## Exploitation

The exploit code is pretty self-explanatory. So go watch the source.

## Stand Setup

1. Clone the repository:
   ```bash
   git clone https://github.com/I3r1h0n/IngressNightterror
   cd IngressNightterror
   ```
2. Start a docker [k3s](https://docs.k3s.io/) image:
    ```bash
    cd stand
    docker compose up -d
    ```
3. Deploy the NGINX Ingress:
    
    In case you're using Linux/Mac, you can deploy it using script:
    ```bash
    ./k8s/setup.sh
    ```
    
    ---
    If you on windows, or want more control over deployment process, do these by hands:
    
    Deploy NGINX Ingress:
    ```bash
    kubectl --kubeconfig=./output/kubeconfig.yaml apply -f ./k8s/ingress.yaml
    ```

    Now you can use kubectl with config providen in `./output`. Don't forget to use namespace `ingress-nginx`.

    > **Important note**: the ingress.yaml is made from [vulnerable NGINX Ingress](https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.9.5/deploy/static/provider/cloud/deploy.yaml) 

## Payload shared object

The payload is simple reverse proxy. Don't forget to edit the port and ip address before building it with:
```bash
make all
```

It will build the shared object using docker container `gcc:latest`.

## Creds

Great respect to the WIZ Research Team who originaly discorved a vulnerability, and to NGINX Ingress mainterners.

prod by _I3r1h0n_.
File Snapshot

[4.0K] /data/pocs/b559500f64dc8ef3739362161721b98a68b1c2e4 ├── [4.0K] exploit │   ├── [ 156] pyproject.toml │   ├── [4.0K] resource │   │   ├── [2.2K] admission.json │   │   └── [ 179] config.toml │   └── [4.0K] src │   └── [4.3K] main.py ├── [2.3M] logo.png ├── [4.0K] payload │   ├── [ 246] Makefile │   └── [4.0K] src │   └── [ 780] main.c ├── [4.2K] README.md └── [4.0K] stand ├── [ 559] docker-compose.yaml └── [4.0K] k8s ├── [ 141] check.sh ├── [ 16K] ingress.yaml └── [ 620] setup.sh 8 directories, 12 files
Shenlong Bot has cached this for you
Remarks
    1. It is advised to access via the original source first.
    2. Local POC snapshots are reserved for subscribers — if the original source is unavailable, the local mirror is part of the paid plan.
    3. Mirroring, verifying, and maintaining this POC archive takes ongoing effort, so local snapshots are a paid feature. Your subscription keeps the archive online — thank you for the support. View subscription plans →