Skip to content
KitploitKITPLOIT
OutilsExploitsBlog
Log in
Soumettre
OutilsExploitsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

FluxContactConfidentialité© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
copy-fail-CVE-2026-31431 — Échec de copie : 732 octets vers root sur chaque grande distribution Linux. | Kitploit
Outils/GitHubGitHub/rio128128/copy-fail-cve-2026-31431
Escalade de PrivilègesSécurité des ConteneursFrameworks d'ExploitationAnalyse des VulnérabilitésExploitationTests d'IntrusionSécurité CloudRed TeamingExploitation de Binaires

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager
GitHubrio128128/copy-fail-cve-2026-31431

copy-fail-CVE-2026-31431

Échec de copie : 732 octets vers root sur chaque grande distribution Linux.

Voir le dépôt
25il y a 5 moisPas encore vérifié

CVE-2026-31431 — Copy Fail

732 octets. Toute distribution. Root.

Une faille logique linéaire dans le modèle cryptographique authencesn du noyau Linux permet à un utilisateur local non privilégié d'effectuer une écriture précise et contrôlée de 4 octets dans le cache de pages de n'importe quel fichier lisible — y compris les binaires setuid. Aucune course. Aucune nouvelle tentative. Aucune recompilation. Root sur toutes les principales distributions Linux publiées depuis 2017.

📄 Analyse technique  ·  🔗 Correctif du noyau  ·  🛡️ CVSS : Critique


Distributions testées

DistributionVersion du noyau
Ubuntu 24.04 LTS6.17.0-1007-aws
Amazon Linux 20236.18.8-9.213.amzn2023
RHEL 10.16.12.0-124.45.1.el10_1
SUSE 166.12.0-160000.9-default

Les quatre ont été compromises avec le même script Python de 732 octets, sans modification.


Ce qui rend cette faille différente

PropriétéDétail
DéterministeFaille logique linéaire — aucune condition de course, aucune fenêtre temporelle, aucune nouvelle tentative
PortableMême script, mêmes octets, fonctionne sur toutes les distributions et architectures testées
MinusculeScript Python de 732 octets utilisant uniquement la bibliothèque standard (os, socket, zlib). Nécessite Python 3.10+ pour os.splice
FurtiveLa page corrompue n'est jamais marquée comme sale. Les sommes de contrôle sur disque sont inchangées ; seule la mémoire cache de pages est modifiée
Trans-conteneurLe cache de pages est partagé à l'échelle du système au-delà des frontières des conteneurs — c'est également une primitive d'évasion de nœud Kubernetes (voir Partie 2)

Cause racine

La configuration : pages du cache de pages dans une liste scatterlist inscriptible

AF_ALG expose le sous-système cryptographique du noyau à l'espace utilisateur non privilégié. splice() transfère les données d'un fichier dans un tube par référence — en transmettant directement les pages du cache de pages, sans copie. Lorsqu'un utilisateur épisse un fichier dans une socket AEAD AF_ALG, la liste scatterlist d'entrée de la socket contient des références vivantes aux pages mises en cache par le noyau de ce fichier.

Dans algif_aead.c, l'optimisation en place de 2017 copiait l'AAD et le texte chiffré de la liste scatterlist TX vers le tampon RX, mais chaînait les pages du tag d'authentification par référence à l'aide de sg_chain(), puis définissait req->src = req->dst :

SGL d'entrée :   [ AAD | CT | Tag ]
                              ^
                              └─ sg_chain() → pointe toujours vers les pages du cache de pages

SGL de sortie :  [ AAD | CT ] ──→ [ Tag (pages du cache de pages) ]
              (tampon RX)       (chaîné depuis le SGL TX)

req->src ──┐
           ├──→ même liste scatterlist combinée
req->dst ──┘

Les pages du cache de pages issues de splice() se retrouvaient désormais dans une liste scatterlist de destination inscriptible, séparées de la zone d'écriture légitime par une simple limite d'offset. Rien dans l'API n'imposait que les algorithmes restent dans les limites.

Le déclencheur : l'écriture hors limites de authencesn

authencesn est un wrapper AEAD utilisé par IPsec pour la prise en charge des Extended Sequence Numbers (ESN) 64 bits. Pour réorganiser les octets ESN pour le calcul HMAC, il utilise le tampon de destination de l'appelant comme espace de travail — y compris une écriture à l'offset assoclen + cryptlen, qui se situe au-delà de la limite du tag d'authentification :

scatterwalk_map_and_copy(tmp,     dst, 0,                       8, 0); // lit AAD[0..7]
scatterwalk_map_and_copy(tmp,     dst, 4,                       4, 1); // écrase dst[4..7]
scatterwalk_map_and_copy(tmp + 1, dst, assoclen + cryptlen,     4, 1); // ← écrit au-delà du tag

Le troisième appel écrit 4 octets (seqno_lo) à dst[assoclen + cryptlen]. Dans le chemin AF_ALG en place, le scatterwalk traverse le tampon RX pour atteindre les pages du tag du cache de pages chaînées. Le noyau mappe la page du cache de pages via kmap_local_page et écrit directement dans la copie mise en cache du fichier cible.

Le HMAC échoue ensuite (le texte chiffré est fabriqué), recvmsg() renvoie une erreur — mais l'écriture de 4 octets persiste définitivement.

Les trois variables contrôlées par l'attaquant

VariableContrôlée via
Fichier cibleTout fichier lisible par l'utilisateur actuel
Offset d'écritureassoclen, offset de splice et longueur de splice
Valeur d'écritureOctets 4–7 de l'AAD fourni dans sendmsg() (seqno_lo)

Comment c'est arrivé : une chaîne de neuf ans

AnnéeÉvénement
2011authencesn ajouté au noyau (a5079d084f8b) pour la prise en charge ESN d'IPsec. L'écriture de travail existait mais était inoffensive — seule la couche interne xfrm l'appelait, et l'AAD se trouvait dans une liste scatterlist séparée.
2015AF_ALG gagne la prise en charge AEAD. authencesn converti à la nouvelle interface AEAD (104880a6b470), introduisant l'offset d'écriture assoclen + cryptlen. Toujours hors place : les pages du cache de pages étaient dans src (lecture seule). Pas encore exploitable.
2017Optimisation en place ajoutée à algif_aead.c (72548b093ee3). req->src = req->dst. Les pages du tag du cache de pages chaînées dans la destination inscriptible. Vulnérabilité formée.
2026-03-23Signalée à l'équipe de sécurité du noyau Linux.
2026-04-01Correctif fusionné dans la branche principale.
2026-04-22CVE-2026-31431 attribuée.
2026-04-29Divulgation publique.

Aucune modification individuelle n'était erronée. La vulnérabilité réside à l'intersection des trois.


Exploit

La cible par défaut est /usr/bin/su, un binaire setuid-root présent sur toutes les distributions testées.

Étape 1 — Configuration de la socket
  Ouvrir une socket AF_ALG, lier à authencesn(hmac(sha256),cbc(aes))
  Définir la clé. Accepter la socket de requête. (Aucun privilège requis.)

Étape 2 — Boucle d'écriture (une fois par bloc de shellcode de 4 octets)
  sendmsg()  →  les octets AAD [4:8] transportent les 4 octets à écrire (seqno_lo)
  splice()   →  les pages du cache de pages du fichier cible dans la socket AF_ALG
  recv()     →  déclenche le déchiffrement → authencesn écrit seqno_lo dans le cache de pages
               (recvmsg renvoie une erreur ; l'écriture persiste)

Étape 3 — Exécution
  execve("/usr/bin/su")
  Le noyau charge le binaire depuis le cache de pages (désormais corrompu)
  Le binaire setuid-root exécute le shellcode injecté → UID 0
a = socket.socket(38, 5, 0)                          # AF_ALG, SOCK_SEQPACKET
a.bind(("aead", "authencesn(hmac(sha256),cbc(aes))"))
# ... définir la clé, accepter la socket de requête u ...
u.sendmsg([b"A"*4 + payload_chunk], [cmsg_headers], MSG_MORE)
os.splice(target_fd, pipe_wr, offset)
os.splice(pipe_rd, alg_fd, offset)
u.recv(...)                                          # déclenche l'écriture dans le cache de pages

Remédiation

Correctif permanent

Télécharger l’outil