F2u0a0d3/CVE-2026-42945-nginx-rift-poc

GitHub: F2u0a0d3/CVE-2026-42945-nginx-rift-poc

Stars: 0 | Forks: 0

# NGINX Rift — CVE-2026-42945 RCE proof-of-concept for **CVE-2026-42945**, a critical heap buffer overflow in NGINX's `ngx_http_rewrite_module` introduced in 2008. Enables unauthenticated remote code execution against servers using `rewrite ... ?...` + `set` capture combinations. Original vulnerability disclosure: [depthfirst](https://depthfirst.com/research/nginx-rift-achieving-nginx-rce-via-an-18-year-old-vulnerability) — found alongside CVE-2026-42946, CVE-2026-40701, CVE-2026-42934 via their autonomous source-audit system. ## Layout poc-CVE-2026-42945/ ├── exploit.py — improved PoC (3 modes: --check / --probe / --exploit) ├── poc.py.orig — original depthfirst PoC (reference) ├── env/ — dual-fixture Docker lab │ ├── Dockerfile (vuln: nginx commit 98fc3bb78) │ ├── Dockerfile.patched (patched: release-1.31.0) │ ├── docker-compose.yml (both services) │ ├── nginx.conf (vulnerable rewrite + set config) │ ├── entrypoint.sh (runs under setarch -R — ASLR off) │ └── server.py (backend stub) ├── discover-addresses.sh — extract HEAP_BASE / LIBC_BASE / system() offset from running container ├── verify.sh — dual-fixture reproducer (exploit vuln, prove patched blocks) ├── setup.sh — build helper (legacy single-image) ├── references.md — full bug mechanics, exploitation strategy, mitigations └── README.md — this file ## The Bug (TL;DR) Two-pass script engine, `is_args` flag desync: - **Length pass** sees `is_args = 0` → allocates raw capture length - **Copy pass** sees `is_args = 1` → `ngx_escape_uri(NGX_ESCAPE_ARGS)` 3x expansion → heap overflow Exploitation: heap feng shui via POST `/spray` body (NUL bytes permitted in body, planted fake `ngx_pool_cleanup_s`) + URI overflow corrupting adjacent `ngx_pool_t.cleanup` head. Pool destruction → `system(cmd)`. Full mechanics + exploitation strategy in [references.md](references.md). ## Affected & Fixed | Product | Affected | Fixed | |-------------------|------------------|--------------------------| | NGINX Open Source | 0.6.27 – 1.30.0 | 1.30.1, 1.31.0 | | NGINX Plus | R32 – R36 | R36 P4, R35 P2, R32 P6 | Vendor advisory: ## Quick Start # Build both fixtures docker compose -f env/docker-compose.yml build # Start lab (vuln=:19321, patched=:19421) docker compose -f env/docker-compose.yml up -d # Detect-only (no overflow trigger) python3 exploit.py --check --host 127.0.0.1 --port 19321 # Full exploit python3 exploit.py --exploit --host 127.0.0.1 --port 19321 \ --cmd 'echo pwned > /tmp/rift' docker exec nginx-rift-vuln cat /tmp/rift # Dual-fixture verify (exploit vuln + confirm patched blocks) ./verify.sh # Teardown docker compose -f env/docker-compose.yml down ## Modes | Mode | Use case | Side effect | |---|---|---| | `--check` | Detect rewrite surface presence | None — sends small probe URIs only | | `--probe` | Enumerate spray-landing offsets for THIS build | Crashes worker(s) during search; no exec | | `--exploit` | Full RCE chain | Worker crash + `system()` call with `--cmd` | Non-localhost targets require `--i-have-tested-this` flag (acknowledgment that hardcoded offsets match the deployed build). ## Address Discovery Default `--heap-base` / `--libc-base` / `--system-offset` are the bundled lab's values (Ubuntu 22.04 / glibc 2.35 / nginx commit 98fc3bb78 / ASLR off). For a fresh build or different libc: docker compose -f env/docker-compose.yml up -d nginx-vuln ./discover-addresses.sh # Copy values into exploit.py invocation ## Caveats - **Lab-only.** Hardcoded offsets are stable only inside the bundled fixture. Production exploitation requires per-target offset derivation (info leak + offset enumeration). - **ASLR.** Lab disables ASLR via `setarch -R`. Real targets have ASLR enabled — additional info-leak primitive required. - **Config dependency.** Vulnerable surface requires `rewrite ... ?` + `set $X $N` combination in the deployed nginx.conf. Many real configs lack this.