Script de détection pour CVE-2026-31431 (Copy Fail) qui vérifie la version du noyau, la présence de correctifs, les configurations du noyau, la disponibilité des sockets AF_ALG, les binaires setuid et les mesures d'atténuation afin de déterminer le statut de vulnérabilité sur les systèmes Linux.
Détection uniquement. Un PoC fonctionnel existe déjà sur copy.fail/#exploit. Ce script est destiné aux administrateurs système et aux équipes de sécurité pour déterminer où ils sont vulnérables — ou encore vulnérables après l'application des correctifs.
Le 29 avril 2026, une vulnérabilité appelée Copy Fail (CVE-2026-31431) a été divulguée publiquement par l'équipe Xint Code Research. Il s'agit d'un bug logique présent discrètement dans le noyau Linux depuis environ 2017 — près d'une décennie — qui permet à tout utilisateur local non privilégié d'obtenir les droits root.
Pas « obtenir root dans des conditions spécifiques avec un peu de chance et un bon vent arrière ». Juste... obtenir root. De manière fiable. Sur pratiquement toutes les principales distributions Linux.
Elle affecte Ubuntu, Amazon Linux, RHEL, SUSE, et tout autre système exécutant un noyau grand public des ~8 dernières années. Même script, pas de recompilation, pas d'ajustements par distribution nécessaires.
Oui, c'est aussi grave que ça en a l'air.
Le noyau Linux dispose d'un sous-système cryptographique accessible aux utilisateurs non privilégiés via les sockets AF_ALG. Il existe un mécanisme appelé splice() qui peut alimenter directement ce sous-système avec des données de fichiers sans les copier — ce qui signifie que la copie en cache mémoire du noyau d'un fichier (le « page cache ») se retrouve à l'intérieur d'une opération cryptographique.
Un algorithme spécifique — authencesn, utilisé pour les numéros de séquence étendus IPsec — présente une particularité : il utilise le tampon de sortie comme espace de travail et écrit 4 octets légèrement au-delà de l'endroit prévu. Normalement inoffensif. Mais lorsque des pages du page cache d'un binaire setuid comme /usr/bin/su se retrouvent chaînées dans ce tampon de sortie (grâce à une « optimisation » de 2017 dans algif_aead.c), ces 4 octets atterrissent directement dans la copie en cache du noyau du binaire.
L'opération échoue avec une erreur. Le noyau ne marque jamais cette page comme sale. Le fichier sur disque est intact. Les outils d'intégrité des fichiers qui vérifient les sommes de contrôle sur disque ne voient rien d'anormal.
Mais c'est le page cache qui est exécuté. Et su est setuid root.
L'analyse technique complète est disponible sur xint.io et vaut vraiment la peine d'être lue.
Sept issues de la version originale plus six nouvelles vérifications ajoutées pour combler les lacunes de détection :
| # | Vérification | Ce qu'elle recherche |
|---|---|---|
| 1 | Version du noyau | Ce noyau est-il dans la plage affectée (4.10–6.14) ? |
| 2 | Présence du correctif | Le commit de correction est-il réellement dans votre noyau en cours d'exécution ? |
| 3 | Module algif_aead | Le module vulnérable est-il chargé ou chargeable ? |
| 4 | CONFIG_CRYPTO_AUTHENC (nouveau) | CONFIG_CRYPTO_AUTHENC est-il intégré (=y) ou en module (=m) ? Cette seule option compile à la fois authenc et authencesn. Intégré signifie que la mitigation par blacklist modprobe ne fait rien. |
| 5 | CONFIG_CRYPTO_USER_API_AEAD (nouveau) | L'interface utilisateur AEAD AF_ALG est-elle même compilée ? Si non, tout le chemin d'exploitation est fermé à la compilation. |
| 6 | Socket AF_ALG | Un utilisateur non privilégié peut-il en ouvrir un maintenant ? |
| 7 | os.splice Python | Le chemin d'exploitation en Python pur est-il disponible ? |
| 8 | Binaires setuid | Liste étendue des cibles setuid-root lisibles présentes sur le système. |
| 9 | Mitigations | AppArmor, SELinux, seccomp — qu'est-ce qui est en place ? |
| 10 | Espaces de noms utilisateur (nouveau) | Les espaces de noms utilisateur non privilégiés sont-ils activés ? (Ne bloque pas Copy Fail directement, mais affecte la surface d'élévation de privilèges locale plus large.) |
| 11 | Transparent hugepages (nouveau) | Statut THP — peut affecter l'alignement du page cache et la fiabilité de l'exploitation. |
| 12 | Détection d'environnement (nouveau) | Contexte Docker/conteneur/VM — les conteneurs partagent le noyau hôte ; c'est l'hôte qui doit être corrigé. |
| 13 | Avertissement utilisateur root (nouveau) | Avertit si exécuté en tant que root, car plusieurs vérifications donnent des faux positifs pour root indépendamment des restrictions non privilégiées. |
Le script Bash couvre la même logique de détection principale mais omet trois éléments spécifiques à Python :
| # | Vérification | Notes |
|---|---|---|
| 1 | Version du noyau | |
| 2 | Présence du correctif | |
| 3 | Module algif_aead | |
| 4 | Socket AF_ALG | Utilise Python comme assistant si disponible ; sinon, déduction à partir de la configuration du noyau |
| 5 | Binaires setuid | Liste étendue, identique à la version Python |
| 6 | Mitigations | AppArmor, SELinux, seccomp |
| 7 | CONFIG_CRYPTO_AUTHENC | |
| 8 | Espaces de noms utilisateur | |
| 9 | Transparent hugepages | |
| 10 | Détection d'environnement |
Absents du script shell (par rapport à Python) :
| Vérification manquante | Raison |
|---|---|
| CONFIG_CRYPTO_USER_API_AEAD | Pas encore implémenté — prévu |
| Disponibilité de os.splice Python | Non applicable à un script shell |
| Avertissement utilisateur root | Pas encore implémenté — prévu |
Aucun des deux scripts ne corrigera ni n'exploitera quoi que ce soit. Ils vous disent la vérité sur votre système afin que vous puissiez agir en conséquence.
# Clonez ou téléchargez le script, puis :
python3 cve-2026-31431-detect.py
C'est tout. Rapport codé par couleurs avec un résumé à la fin.
Le script se termine avec un code non nul en cas de résultats vulnérables, ce qui le rend adapté à une utilisation en pipeline :
| Code | Signification |
|---|---|
0 | Aucune condition vulnérable trouvée |
1 | Une ou plusieurs conditions vulnérables trouvées |
# Exemple : faire échouer une étape CI si l'hôte est vulnérable
python3 cve-2026-31431-detect.py
rc=$?
if [ $rc -eq 1 ]; then
echo "VULNÉRABLE — bloquer le déploiement"
elif [ $rc -ne 0 ]; then
echo "ERREUR — le script n'a pas pu se terminer (code de sortie $rc)"
fi
CVE-2026-31431 'Copy Fail' — Détection de vulnérabilité
Corruption du page cache authencesn / élévation de privilèges locale
Exécution avec uid=1001, euid=1001
=== Version du noyau ===
[VULNÉRABLE] Version du noyau
Raison : Le noyau est dans la plage vulnérable (4.10 – 6.14)
Détail : Version : 6.12.0-124.45.1.el10_1 — le statut du correctif doit être confirmé
=== CONFIG_CRYPTO_AUTHENC (Configuration du noyau) ===
[VULNÉRABLE] CONFIG_CRYPTO_AUTHENC
Raison : Compilé en module (=m) : chargement automatique sur bind() AF_ALG ; la blacklist modprobe est la mitigation correcte