
Analyse détaillée de la vulnérabilité Copy Fail (CVE-2026-31431) dans le noyau Linux, incluant le mécanisme de corruption mémoire, le flux d'élévation de privilèges et l'impact sur la sécurité.
Analyse pédagogique de la vulnérabilité Copy Fail dans le noyau Linux.
Couvre le mécanisme de corruption mémoire, le flux d'élévation de privilèges, l'évasion de conteneur et les contre-mesures défensives.
Ce dépôt est destiné uniquement à des fins éducatives et de recherche.
N'utilisez pas ces informations sur des systèmes qui ne vous appartiennent pas ou pour lesquels vous n'avez pas d'autorisation écrite explicite de test.
Tous les extraits de code et commandes sont fournis strictement pour aider à comprendre les mécanismes internes du noyau Linux.
CVE-2026-31431, également connue sous le nom de Copy Fail, est une vulnérabilité du noyau Linux où un utilisateur local non privilégié peut passer à root sans aucune permission spéciale.
L'attaque opère entièrement en RAM. Le fichier sur disque n'est jamais touché — les empreintes de fichiers restent propres, les horodatages sont inchangés et les journaux d'audit n'enregistrent rien. Lorsque le système redémarre, toutes les preuves disparaissent.
Utilisateur normal → exploit du bug algif_aead → écrasement du cache de pages → root
Propriétés clés :
| Champ | Valeur |
|---|---|
| ID CVE | CVE-2026-31431 |
| Nom courant | Copy Fail / Corruption du cache de pages algif_aead |
| Score CVSS v3.1 | 7.8 — CRITIQUE |
| Type d'attaque | Élévation de privilèges locale (LPE) |
| Versions du noyau affectées | Linux 5.10 à 6.8 (environ) |
| Composant vulnérable | crypto/algif_aead.c — interface socket AF_ALG |
| Fiabilité de l'exploitation | ÉLEVÉE — Aucune condition de course requise |
| Preuve sur disque | AUCUNE — modification en RAM uniquement |
| Impact conteneur | OUI — Évasion hôte via le cache de pages partagé |
| État du correctif | Disponible (correctif du noyau en amont publié) |
/usr/bin/su — Le binaire ciblesu (Switch User) permet à un utilisateur de basculer vers un autre compte — généralement root. C'est un binaire SetUID :
ls -l /usr/bin/su
# -rwsr-xr-x 1 root root 68208 Jan 1 2026 /usr/bin/su
# ^-- 's' = indicateur SetUID
L'indicateur s signifie : lorsque n'importe quel utilisateur exécute ce binaire, il s'exécute avec les permissions de root. Cela en fait une cible de grande valeur.
Sa logique interne (simplifiée) :
if (password_correct()) {
give_root_access();
} else {
deny_access();
}
L'objectif de l'attaque : contourner entièrement la vérification password_correct().
Lorsque Linux lit un fichier depuis le disque, il en conserve une copie en RAM appelée le cache de pages.
| Composant | Description |
|---|---|
| Disque | Fichier original sur disque (l'étagère de bibliothèque) |
| Cache de pages | Copie RAM du fichier (la photocopie sur votre bureau) |
| CPU | Lit et exécute depuis le cache de pages — rapide |
| Attaquant | Modifie la copie RAM ; le disque reste intact |
cat /proc/meminfo | grep Cached
# Cached: 1234567 kB ← c'est le cache de pages
| Type | Sécurité |
|---|---|
| Tampon sûr — alloué par le noyau, taille et limites contrôlées | ✅ OK |
| Cache de pages — copie RAM adossée à un fichier, partagée, exécutable | ⚠️ DANGEREUX si écrit |
| Pointeur erroné — adresse causée par un bug pointant n'importe où | 🔴 CRITIQUE |
AF_ALG (Algorithm Family) est une interface socket Linux qui permet aux programmes en espace utilisateur d'utiliser les fonctions cryptographiques du noyau (AES, SHA, AEAD).
socket(AF_ALG, SOCK_SEQPACKET, 0); // ouvre une socket cryptographique
algif_aead est le module du noyau qui gère le chiffrement AEAD (par ex. AES-GCM) via AF_ALG. La vulnérabilité réside dans son étape de copie de données.
AF_ALG → algif_aead → moteur AES-GCM → tampon de sortie
↑
LE BUG EST ICI
Le bug n'est pas dans la logique de chiffrement. Il est dans la gestion mémoire — la mauvaise région mémoire est sélectionnée lors d'une copie de données.
destination = safe_output_buffer; // emplacement correct
memcpy(destination, user_data, size); // données écrites en toute sécurité
destination = buffer + WRONG_OFFSET; // BUG : mauvais pointeur !
memcpy(destination, user_data, size); // les données atterrissent dans le cache de pages
Le noyau était censé écrire dans le tampon de sortie sûr. En raison d'un décalage mal calculé, il écrit dans le cache de pages — qui contient la copie RAM de /usr/bin/su.
Le binaire contient du code machine x86-64. L'attaquant cible le saut conditionnel qui déclenche l'échec d'authentification :
Avant l'attaque :
cmp eax, 0 ; vérifie la valeur de retour
jne 0x1234 ; si échec → saute vers le refus
call give_root ; accorde root
Après l'attaque (2 octets modifiés en RAM) :
cmp eax, 0 ; identique
90 90 ; NOP NOP ← saut remplacé, vérification contournée !
call give_root ; le CPU arrive directement ici
NOP = No Operation (aucune opération). Le CPU ne fait rien et avance — contournant entièrement la vérification d'authentification.
« Je n'ai besoin que d'un compte utilisateur normal. Le noyau fera l'erreur lui-même.
Le disque reste propre. Aucun journal. Fonctionne à chaque fois. »
whoami && id
# uid=1000(user) gid=1000(user) ← utilisateur normal
uname -r
# 6.1.0-generic ← dans la plage vulnérable
ls -la /usr/bin/su
# -rwsr-xr-x root root ← SetUID confirmé
python3 -c "import socket; s = socket.socket(socket.AF_ALG); print('AF_ALG disponible')"
cat /usr/bin/su > /dev/null
# /usr/bin/su est maintenant chargé dans le cache de pages ✓
xxd /usr/bin/su | head -50
objdump -d /usr/bin/su | grep -A 20 'check\|auth\|pass'
readelf -h /usr/bin/su
Recherche : l'adresse de la fonction d'authentification, le saut conditionnel jne/jnz, et son décalage d'octet exact.
import socket, struct