
Une implémentation Bash de copyfail (CVE-2026-31431)
Pas de condition de course. Pas d'offsets. Pas de binaire précompilé à croire aveuglément.
Une implémentation en bash de CVE-2026-31431 (Copy Fail). Le script compile un helper C minimal en ligne lors de l'exécution. La couche bash gère la détection d'architecture, la décompression de la charge utile et la sélection de la cible ; la couche C effectue l'interaction réelle avec le noyau (sockets AF_ALG, splice, sendmsg) que bash ne peut pas atteindre seul.
Voir copy.fail pour la description technique complète.
Le bug se trouve dans algif_aead, l'interface socket AF_ALG AEAD du noyau. Une optimisation sur place de 2017 permet aux pages du cache de pages de se retrouver dans la liste de diffusion de destination accessible en écriture d'une opération de déchiffrement authencesn. En fournissant la bonne entrée via splice(), vous obtenez une écriture déterministe de 4 octets dans le cache de pages de n'importe quel fichier lisible, y compris les binaires setuid que vous ne possédez pas.
Écrasez /usr/bin/su avec un shellcode 4 octets à la fois, exécutez-le, obtenez un shell root. Pas de fenêtre de compétition, pas de symboles spécifiques au noyau, pas de tentatives.
chmod +x copyfail.sh
# Vérifiez si le système est vulnérable avant de faire quoi que ce soit
./copyfail.sh -c
# Exécutez l'exploit (doit être non-root)
./copyfail.sh
# Spécifiez une cible setuid différente
./copyfail.sh -t /usr/bin/passwd
# Listez tous les candidats setuid-root sur le système
./copyfail.sh -s
L'exploit écrase uniquement le cache de pages en mémoire, le fichier sur le disque est intact. Un redémarrage restaure tout. Si vous voulez nettoyer immédiatement :
# Dans votre shell root
/usr/bin/su --version # fonctionne toujours depuis le disque si le cache de pages est évincé
# Ou redémarrez simplement
Si vous avez utilisé -t avec autre chose que su, même principe. Cache de pages uniquement, disque propre.
gcc pour compiler le helper C en lignepython3 pour décompresser la charge utile shellcode (une ligne, aucun paquet nécessaire)algif_aead, authencesn, hmac, cbcSi l'algorithme n'est pas disponible :
sudo modprobe algif_aead authencesn hmac cbc
Certaines distributions livrent un bloc dans /etc/modprobe.d/ comme solution de contournement temporaire. Supprimez-le s'il est présent :
sudo rm /etc/modprobe.d/disable-algif{_,-}aead.conf 2>/dev/null
plancher : torvalds/linux 72548b093ee3 août 2017, v4.14
(remaniement iov_iter d'AF_ALG qui a introduit
la primitive d'écriture dans les pages de fichiers
via splice dans la liste de diffusion AEAD)
plafond : torvalds/linux a664bf3d603d avril 2026, mainline
(annule l'optimisation sur place de 2017 ;
les listes de diffusion source et destination sont
désormais séparées, les pages du cache de pages ne
peuvent plus se retrouver comme sortie crypto accessible
en écriture)
Entre ces deux commits : toutes les distributions majeures qui n'ont pas porté le correctif. Ubuntu, RHEL, SUSE, Amazon Linux, Debian ont toutes été confirmées vulnérables au moment de la divulgation. Les rétroportages des distributions ont commencé à arriver vers le 2026-04-29. Pour vérifier un noyau spécifique, cherchez a664bf3d603d (ou son rétroportage de distribution) dans le journal des modifications.
| Architecture | État |
|---|---|
| x86_64 | ✓ |
| aarch64 | ✓ |
| i386 / i686 | ✓ |
| armv7l | ✓ |
Permanent : mettez à jour votre noyau.
Solution de contournement (bloque la socket AF_ALG ; n'affecte pas IPsec/XFRM qui utilise directement l'API crypto du noyau) :
echo "install algif_aead /bin/false" | sudo tee /etc/modprobe.d/disable-algif-aead.conf
sudo rmmod algif_aead 2>/dev/null
Conteneurs : ajoutez un profil seccomp qui bloque la création de socket AF_ALG, et définissez allowPrivilegeEscalation: false dans votre contexte de sécurité de pod. Cela active no_new_privs qui empêche le noyau d'honorer les bits setuid lors de execve().
La version bash ne gagne pas sur les dépendances, mais c'est un script unique que vous pouvez lire de bout en bout avant de l'exécuter. Le helper C est généré et compilé à l'exécution à partir d'un heredoc, aucun binaire à auditer séparément.
Pour les tests de sécurité et la recherche autorisés uniquement. N'exécutez pas ceci sur des systèmes que vous ne possédez pas ou pour lesquels vous n'avez pas d'autorisation écrite explicite de tester.
| Python | Go | Bash |
|---|
| Dépendance | python3 | aucun (binaire statique) | gcc + python3 |
| Binaire précompilé | non | oui | non |
| Fichier unique | oui | non | oui |
| Étape de compilation | non | non | oui (en ligne, automatique) |