
# Exploit di escalation dei privilegi locali per CVE-2026-31431, una sovrascrittura della page-cache AF_ALG + splice nel kernel Linux. Include PoC, script di rilevamento BPFtrace e ambiente di test QEMU per ricerca sulla sicurezza autorizzata.
Escalata di privilegi locale nel kernel Linux tramite AF_ALG + sovrascrittura della page cache con splice
Solo per ricerca sulla sicurezza autorizzata, test di penetrazione e scopi educativi. Non utilizzare contro sistemi di cui non si è proprietari o per i quali non si dispone di esplicita autorizzazione scritta al test.
CVE-2026-31431 è una vulnerabilità di escalation dei privilegi locale (LPE) nel kernel Linux. Un
utente locale non privilegiato può ottenere accesso root combinando l'interfaccia socket AF_ALG con
splice() per eseguire una scrittura autenticata direttamente in una pagina della page cache appartenente a un
binario setuid.
L'exploit sovrascrive il binario su nella page cache senza modificare l'inode su disco,
bypassando i meccanismi di integrità che si basano esclusivamente sui metadati dei file o sui checksum a livello di blocco.
| Campo | Valore |
|---|---|
| ID CVE | CVE-2026-31431 |
| Tipo | Escalation dei Privilegi Locale (LPE) |
| Punteggio CVSS v3.1 | 7.8 Alto — AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H (fonte: kernel.org) |
| Sottosistemi kernel | crypto/af_alg.c, mm/splice.c |
| Vettore di attacco | Locale — richiesto account utente non privilegiato |
| Causa principale | algif_aead accetta sendfile() su un socket AEAD senza imporre la semantica copy-on-write sulla pagina della page cache mappata prima che splice() completi il trasferimento |
| Distribuzione | Versione kernel | Arch |
|---|---|---|
| Ubuntu 24.04 LTS | 6.17.0-1007-aws | x86_64 |
| Amazon Linux 2023 | 6.18.8-9.213.amzn2023 | x86_64 |
| RHEL 10.1 | 6.12.0-124.45.1.el10_1 | x86_64 |
| SUSE 16 | 6.12.0-160000.9-default | x86_64 |
| Raspberry Pi OS (Pi 5) | 6.12.75+rpt-rpi-2712 | aarch64 |
.
├── exploit.py # PoC — sovrascrittura della page cache ed escalation dei privilegi
├── detect.bt # Script BPFtrace per il rilevamento in tempo reale
├── run-vm.sh # Automazione ambiente di test QEMU (opzionale)
├── PAYLOAD.md # Analisi della codifica del payload (hex → zlib → ELF → shellcode)
└── LICENSE
Esegui exploit.py come utente locale non privilegiato su qualsiasi sistema vulnerabile — non serve sudo:
python3 exploit.py
Lo script esegue i seguenti passaggi:
AF_ALG (algif_aead) e individua il binario su.su come descrittore di file grezzo e sovrascrive le sue pagine nella page cache tramite
AF_ALG + sendfile.Architetture supportate:
| Architettura | Varianti |
|---|---|
| x86_64 | — |
| aarch64 | — |
| riscv64 | — |
| ppc64le | — |
| arm | armv5l, armv6l, armv7l |
| x86 32-bit | i386, i486, i586, i686 |
| MIPS 64-bit | mips64, mips64el |
| LoongArch | loong64, loongarch64 |
| s390x | — |
Monitora i tentativi di sfruttamento in tempo reale con detect.bt. Richiede root:
sudo bpftrace detect.bt
# oppure
doas bpftrace detect.bt
Lo script traccia tre indicatori per PID utilizzando una bitmask in @suspect[pid]:
| Bit | Syscall | Indicatore |
|---|---|---|
0x1 | socket(AF_ALG, SOCK_SEQPACKET) | Socket AF_ALG creato |
0x2 | setsockopt(SOL_ALG, ...) | Operazione crittografica configurata |
0x4 | sendmsg(MSG_MORE) + splice() | Tentativo di sovrascrittura della page cache |
Un avviso scatta quando tutti e tre i bit sono impostati (@suspect[pid] == 0x7) sullo stesso PID.
exploit.pyAF_ALG/algif_aead caricatodetect.btbpftrace ≥ 0.12# Ubuntu/Debian
sudo apt install bpftrace
# RHEL/CentOS/Fedora
sudo dnf install bpftrace
# Amazon Linux
sudo yum install bpftrace
# SUSE
sudo zypper install bpftrace
# Alpine
sudo apk add bpftrace
Aggiorna il pacchetto kernel della tua distribuzione a una versione che includa il commit mainline
a664bf3d603d,
che annulla l'ottimizzazione in-place del 2017 di algif_aead in modo che le pagine della page cache non possano più
finire nello scatterlist di destinazione scrivibile. La maggior parte delle principali distribuzioni sta
distribuendo la correzione.
algif_aead (in attesa di una patch)La blacklist può essere aggirata con un modprobe algif_aead esplicito. La direttiva install .../bin/false
sovrascrive completamente il comando di installazione, facendo fallire ogni tentativo di caricamento:
echo "install algif_aead /bin/false" | sudo tee /etc/modprobe.d/disable-algif.conf
sudo rmmod algif_aead 2>/dev/null || true