Understanding the Dry-Run Mode in IngressNightmare: CVE-2025-1974 Testing Safety
The dry-run mode in IngressNightmare is a safety mechanism triggered by the -d or --dry-run flag that prevents network interaction with the target cluster and outputs the generated exploit payload to stdout instead.
The esonhugh/ingressnightmare-cve-2025-1974-exps repository provides a proof-of-concept tool for testing ingress-nginx vulnerabilities. When using this exploitation framework, the dry-run mode serves as a critical safeguard to inspect payloads before they are transmitted, preventing accidental execution against production environments.
How Dry-Run Mode Works in IngressNightmare
The dry-run functionality acts as a circuit breaker between payload generation and network transmission. When enabled, the tool intercepts execution at three specific points in the control flow, ensuring that no HTTP requests reach the ingress-nginx webhook or upload endpoints.
Flag Definition in main.go
The dry-run capability is defined in main.go line 92 as a boolean flag:
// Command-line flag definition
-d, --dry-run Enable dry-run mode (no actual exploit execution)
Once parsed, the Opts.DryRun boolean is evaluated at strategic execution branches to determine whether to proceed with network operations or print the payload locally.
Execution Paths Where Dry-Run Intercepts Operations
The Opts.DryRun variable is consulted in three distinct code locations within main.go, each corresponding to a different operational mode:
1. Admission Validation Mode (main.go lines 202-206)
When running with --mode validate, the tool generates a JSON validation request using the validate.json template. If dry-run is enabled, the tool prints the ValidateJSON payload (with the targeted file path substituted) to stdout and exits before calling nginx_ingress.OnlyAdmissionRequest().
2. Upload-Only Mode (main.go lines 227-231)
In upload-only operations, the tool constructs binary payloads such as reverse-shells or bind-shells defined in payload.go. With dry-run active, the binary data is written to stdout immediately after generation, preventing the execution of nginx_ingress.Exploit().
3. Default Exploit Path (main.go lines 267-271)
During standard exploitation workflows, the fully constructed payload is printed to the console rather than transmitted. This occurs after payload assembly but before any TCP connection establishment with the target ingress-nginx controller.
Practical Use Cases for Dry-Run Mode
Security researchers and cluster administrators utilize dry-run mode for several verification purposes:
- Payload Verification: Confirm that JSON webhook validation requests contain the correct file paths and admission review objects before transmission
- Binary Inspection: Examine the exact byte structure of reverse-shell, bind-shell, or command payloads generated by the
exploit.gologic - Template Validation: Verify that substitutions in
validate.jsonproduce syntactically correct Kubernetes AdmissionReview objects - Safety Testing: Validate command-line arguments and payload construction in isolated environments without risking unintended exploitation of production clusters
Using Dry-Run Mode: Code Examples
The following commands demonstrate practical usage of the dry-run flag across different operational modes:
# Display the validation JSON that would be sent to the admission webhook
# (no actual HTTP request is made)
./ingressnightmare ingress-nightmare --mode validate -d
# Build a reverse-shell payload and output to stdout without sending
./ingressnightmare ingress-nightmare -m reverse-shell -r 10.0.0.5 -p 4444 -d
# Preview a command execution payload before transmission
./ingressnightmare ingress-nightmare -m command -c "id" --dry-run
In each scenario, the tool outputs the exact data structure that would normally be passed to nginx_ingress.Exploit() or nginx_ingress.OnlyAdmissionRequest(), allowing for inspection and debugging.
Implementation Details and Source Code References
The dry-run logic is tightly integrated with the tool's core execution flow in main.go. When Opts.DryRun evaluates to true, the application bypasses calls to the exploitation engine defined in exploit.go and payload constructors from payload.go.
The validate.json template serves as the foundation for the admission validation payload displayed during dry-run execution. This template is parsed, populated with target-specific variables, and then printed to stdout rather than being embedded in an HTTP POST request to the webhook endpoint.
Summary
- Dry-run mode in IngressNightmare is controlled by the
-dor--dry-runcommand-line flag defined inmain.go. - When enabled, the tool outputs payloads to stdout instead of transmitting them to the target cluster.
- The safety check operates at three specific code locations covering validation, upload-only, and default exploit modes.
- This mode allows verification of JSON admission requests and binary payloads without network side effects.
- The implementation prevents execution of
nginx_ingress.Exploit()and related functions while preserving full payload generation logic.
Frequently Asked Questions
What is the dry-run mode in IngressNightmare?
The dry-run mode is a safety feature that prevents the tool from contacting the target Kubernetes cluster or uploading exploit payloads. Instead of executing the CVE-2025-1974 exploit chain, it prints the generated payload data to stdout for inspection and verification.
How do I enable dry-run mode?
Enable dry-run mode by appending the -d or --dry-run flag to any IngressNightmare command. For example: ingressnightmare -m reverse-shell -r 127.0.0.1 -p 9001 -d. The flag is parsed in main.go and affects all execution paths including validation and exploit modes.
Does dry-run mode connect to the Kubernetes cluster?
No. When dry-run mode is active, IngressNightmare does not establish any network connections to the ingress-nginx webhook or the target cluster. The tool exits after printing the payload locally, ensuring zero network footprint and preventing accidental exploitation.
Where is the dry-run logic implemented?
The dry-run logic is implemented in main.go at lines 202-206, 227-231, and 267-271. These locations correspond to the admission validation path, upload-only mode, and default exploit execution flow respectively, each checking the Opts.DryRun boolean before proceeding with network operations.
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 →