Script di rilevamento per CVE-2026-31431 (Copy Fail) che verifica la versione del kernel, la presenza di patch, le configurazioni del kernel, la disponibilità dei socket AF_ALG, i binari setuid e le mitigazioni per determinare lo stato di vulnerabilità sui sistemi Linux.
Solo rilevamento. Un PoC funzionante esiste già su copy.fail/#exploit. Questo script è pensato per sysadmin e team di sicurezza che devono determinare dove sono vulnerabili — o ancora vulnerabili dopo l'applicazione delle patch.
Il 29 aprile 2026, una vulnerabilità chiamata Copy Fail (CVE-2026-31431) è stata divulgata pubblicamente dal Xint Code Research Team. È un bug logico presente silenziosamente nel kernel Linux da circa 2017 — quasi un decennio — e consente a qualsiasi utente locale non privilegiato di ottenere root.
Non "ottenere root in condizioni specifiche con un po' di fortuna e un vento favorevole." Semplicemente... ottenere root. In modo affidabile. Praticamente su ogni principale distribuzione Linux.
Colpisce Ubuntu, Amazon Linux, RHEL, SUSE e qualsiasi altro sistema che esegue un kernel mainstream degli ultimi ~8 anni. Stesso script, nessuna ricompilazione, nessuna modifica per distribuzione richiesta.
Sì, è grave quanto sembra.
Il kernel Linux ha un sottosistema crittografico accessibile agli utenti non privilegiati tramite socket AF_ALG. Esiste un meccanismo chiamato splice() che può inoltrare dati di file direttamente in quel sottosistema senza copiarli — il che significa che la copia cache in memoria del kernel di un file (la "page cache") finisce all'interno di un'operazione crittografica.
Un algoritmo specifico — authencesn, usato per i numeri di sequenza estesi IPsec — ha una particolarità: usa il buffer di output come spazio di lavoro e scrive 4 byte leggermente oltre la posizione prevista. Normalmente innocuo. Ma quando le pagine della page cache di un binario setuid come /usr/bin/su finiscono concatenate in quel buffer di output (grazie a una "ottimizzazione" del 2017 in algif_aead.c), quei 4 byte finiscono direttamente nella copia cache del binario nel kernel.
L'operazione fallisce con un errore. Il kernel non marca mai quella pagina come sporca. Il file su disco è intatto. Gli strumenti di integrità dei file che verificano i checksum su disco non rilevano nulla di anomalo.
Ma la page cache è ciò che viene eseguito. E su è setuid root.
Il resoconto tecnico completo è su xint.io e merita davvero di essere letto.
Sette dalla versione originale più sei nuovi controlli aggiunti per colmare le lacune di rilevamento:
| # | Controllo | Cosa cerca |
|---|---|---|
| 1 | Versione del kernel | Questo kernel è nell'intervallo interessato (4.10–6.14)? |
| 2 | Presenza della patch | Il commit di correzione è effettivamente nel kernel in esecuzione? |
| 3 | Modulo algif_aead | Il modulo vulnerabile è caricato o caricabile? |
| 4 | CONFIG_CRYPTO_AUTHENC (nuovo) | CONFIG_CRYPTO_AUTHENC è integrato (=y) o un modulo (=m)? Questa singola opzione compila sia authenc che authencesn. Integrato significa che la mitigazione con blacklist di modprobe non serve a nulla. |
| 5 | CONFIG_CRYPTO_USER_API_AEAD (nuovo) | L'interfaccia utente AF_ALG AEAD è persino compilata? Se no, l'intero percorso di exploit è chiuso in fase di compilazione. |
| 6 | Socket AF_ALG | Un utente non privilegiato può aprirne uno adesso? |
| 7 | Python os.splice | Il percorso di exploit in puro Python è disponibile? |
| 8 | Binari setuid | Elenco esteso di target setuid-root leggibili presenti sul sistema. |
| 9 | Mitigazioni | AppArmor, SELinux, seccomp — cosa c'è in atto? |
| 10 | Namespace utente (nuovo) | I namespace utente non privilegiati sono abilitati? (Non blocca direttamente Copy Fail, ma influisce sulla più ampia superficie di privesc locale.) |
| 11 | Hugepage trasparenti (nuovo) | Stato THP — può influire sull'allineamento della page cache e sull'affidabilità dell'exploit. |
| 12 | Rilevamento ambiente (nuovo) | Contesto Docker/container/VM — i container condividono il kernel dell'host; è l'host che deve essere patchato. |
| 13 | Avviso utente root (nuovo) | Avvisa se si esegue come root, poiché diversi controlli danno falsi positivi per root indipendentemente dalle restrizioni per non privilegiati. |
Lo script Bash copre la stessa logica di rilevamento principale ma omette tre elementi specifici di Python:
| # | Controllo | Note |
|---|---|---|
| 1 | Versione del kernel | |
| 2 | Presenza della patch | |
| 3 | Modulo algif_aead | |
| 4 | Socket AF_ALG | Usa Python come helper se disponibile; altrimenti ripiega sull'inferenza dalla configurazione del kernel |
| 5 | Binari setuid | Elenco esteso, come nella versione Python |
| 6 | Mitigazioni | AppArmor, SELinux, seccomp |
| 7 | CONFIG_CRYPTO_AUTHENC | |
| 8 | Namespace utente | |
| 9 | Hugepage trasparenti | |
| 10 | Rilevamento ambiente |
Non presenti nello script shell (rispetto a Python):
| Controllo mancante | Motivo |
|---|---|
| CONFIG_CRYPTO_USER_API_AEAD | Non ancora implementato — pianificato |
| Disponibilità Python os.splice | Non applicabile a uno script shell |
| Avviso utente root | Non ancora implementato — pianificato |
Nessuno dei due script risolve o sfrutta nulla. Ti dicono la verità sul tuo sistema così puoi agire di conseguenza.
# Clona o scarica lo script, poi:
python3 cve-2026-31431-detect.py
Tutto qui. Report con codici colore e un riepilogo alla fine.
Lo script esce con un codice non zero in caso di risultati vulnerabili, rendendolo adatto all'uso in pipeline:
| Codice | Significato |
|---|---|
0 | Nessuna condizione vulnerabile trovata |
1 | Una o più condizioni vulnerabili trovate |
# Esempio: fai fallire uno step CI se l'host è vulnerabile
python3 cve-2026-31431-detect.py
rc=$?
if [ $rc -eq 1 ]; then
echo "VULNERABILE — blocca il deployment"
elif [ $rc -ne 0 ]; then
echo "ERRORE — lo script non è riuscito a completare (exit $rc)"
fi
CVE-2026-31431 'Copy Fail' — Rilevamento vulnerabilità
Corruzione page cache authencesn / escalation privilegi locale
Esecuzione come uid=1001, euid=1001
=== Versione del kernel ===
[VULNERABILE] Versione del kernel
Motivo : Il kernel è nell'intervallo vulnerabile (4.10 – 6.14)
Dettaglio : Release: 6.12.0-124.45.1.el10_1 — lo stato della patch deve essere confermato
=== CONFIG_CRYPTO_AUTHENC (Configurazione kernel) ===
[VULNERABILE] CONFIG_CRYPTO_AUTHENC
Motivo : Compilato come modulo (=m): si carica automaticamente su bind() AF_ALG; la blacklist di modprobe è la mitigazione corretta
=== CONFIG_CRYPTO_USER_API_AEAD (Configurazione kernel) ===
[VULNERABILE] CONFIG_CRYPTO_USER_API_AEAD
Motivo : L'interfaccia AEAD AF_ALG è un modulo caricabile — gli utenti non privilegiati possono accedere al sottosistema crittografico tramite socket AF_ALG
...
IL SISTEMA È PROBABILMENTE VULNERABILE A CVE-2026-31431