Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
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é.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
Outils/GitHubGitHub/galoryber/cve-2026-31431-cleaned
Escalade de PrivilègesFrameworks d'ExploitationAnalyse des VulnérabilitésExploitationExploitation de Binaires
GitHubgaloryber/cve-2026-31431-cleaned

CVE-2026-31431-cleaned

Preuve de concept d'exploitation pour CVE-2026-31431, une élévation de privilèges locale du noyau Linux via splice() et des options de socket malveillantes, permettant une écriture arbitraire dans la mémoire du noyau afin d'écraser les binaires setuid.

Voir le dépôt
14il y a 4 moisPas encore vérifié

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

copyFail.py — Rapport d'analyse de l'exploit CVE

Résumé

copyFail.py est un exploit de preuve de concept (PoC) qui démontre une vulnérabilité d'élévation de privilèges locale dans le noyau Linux. En abusant de l'appel système splice() combiné à des options de socket savamment conçues, l'exploit obtient la capacité de corrompre la mémoire arbitraire du noyau. Il utilise cette capacité pour écraser n'importe quel binaire setuid sur le disque avec un exécutable ELF personnalisé, puis exécute le binaire falsifié pour obtenir des privilèges élevés.

Type d'attaque : Élévation de privilèges locale (LPE) Impact : Accès complet à un shell root (en ciblant les binaires setuid-root) Complexité : Faible (script unique, aucune dépendance externe)

Utilisation :

root@kitploit:~
./copyFail_cleaned.py [binaire_cible]   # par défaut : /usr/bin/su

Le PoC original codait en dur /usr/bin/su, mais la vulnérabilité sous-jacente du noyau s'applique à n'importe quel fichier — l'attaquant peut écraser n'importe quel binaire setuid de son choix. La version nettoyée accepte un argument de ligne de commande optionnel pour spécifier la cible, rendant ce comportement explicite.


Ce qu'est la vulnérabilité

Le noyau Linux fournit un appel système splice() qui copie des données entre deux descripteurs de fichiers entièrement dans le noyau — sans copier les données dans l'espace utilisateur au préalable. C'est ce qu'on appelle les « E/S zéro-copie » et cela est utilisé pour les performances dans les applications à haut débit comme les serveurs web et les proxys inverses.

La vulnérabilité provient du fait que le noyau ne valide pas correctement l'état interne de certaines structures de socket lorsque splice() est utilisé sur des sockets PACKET configurées avec des options de socket de niveau protocole non prises en charge. En concevant soigneusement ces options, un attaquant peut corrompre des pointeurs du noyau, puis utiliser splice() pour rediriger les écritures mémoire du noyau vers des emplacements arbitraires.

En termes simples : le noyau dispose d'un raccourci pour déplacer des données en interne, et cet exploit trompe ce raccourci pour écrire des données au mauvais endroit — plus précisément, dans la copie en mémoire d'un binaire système.


Comment fonctionne l'exploit (vue d'ensemble)

L'exploit suit une séquence claire d'étapes :

1. Configuration d'un socket malformé

L'exploit crée un socket PACKET brut (AF_PACKET / SOCK_RAW) et le lie à des adresses intentionnellement malformées. Il appelle ensuite setsockopt() en utilisant SOL_PNIO (niveau de protocole 279), une constante de niveau Solaris que Linux ne reconnaît pas.

Pourquoi c'est important : Lorsque le noyau rencontre un niveau de protocole non pris en charge dans setsockopt(), il retombe sur un gestionnaire générique qui ne valide pas correctement les données. Cela laisse la mémoire du noyau dans un état incohérent et exploitable.

2. Corruption des pointeurs du noyau avec sendmsg()

Après avoir établi une connexion socket via accept(), l'exploit envoie des messages de contrôle (ancillaires) conçus avec soin en utilisant sendmsg(). Ces messages ont des en-têtes de longueur volontairement incohérents — certains prétendent être plus courts qu'ils ne le sont, d'autres plus longs.

Pourquoi c'est important : L'analyseur de messages de contrôle du noyau utilise ces longueurs pour l'arithmétique des pointeurs. Des longueurs incohérentes amènent l'analyseur à lire ou écrire au-delà des limites prévues, corrompant les structures adjacentes du noyau — en particulier, les pointeurs que splice() suivra ensuite.

3. Redirection de splice() pour écraser la mémoire arbitraire

L'exploit crée un tube et appelle splice() deux fois :

  • D'abord, il épisse les données de /usr/bin/su dans le tube.
  • Ensuite, il épisse du tube vers le socket corrompu.

Pourquoi c'est important : L'appel splice() suit les pointeurs du noyau corrompus implantés à l'étape 2, ce qui l'amène à écrire des données vers une adresse mémoire du noyau choisie par l'attaquant au lieu du tampon du socket. Cela donne à l'exploit une primitive d'écriture mémoire arbitraire dans le noyau.

4. Répétition pour chaque morceau de shellcode

La charge utile de l'exploit est un exécutable ELF de 160 octets (voir ci-dessous). Chaque appel à la fonction d'exploit écrit exactement 4 octets. La boucle principale s'exécute donc 40 fois (160 / 4 = 40), à chaque fois :

  • Création d'un nouveau socket
  • Corruption de l'état du noyau
  • Écriture de 4 octets de shellcode
  • Nettoyage

Après les 40 itérations, les 160 premiers octets de /usr/bin/su ont été écrasés.

5. Exécution du binaire falsifié

Enfin, l'exploit exécute os.system("su"). Le noyau charge le /usr/bin/su modifié depuis son cache de pages (qui contient désormais le shellcode de l'attaquant au lieu du vrai binaire su), et le shellcode s'exécute.


La charge utile du shellcode

La charge utile intégrée se décompresse en un exécutable ELF x86-64 de 160 octets contenant ce shellcode :

root@kitploit:~
; Tentative de l'appel système 105 (execveat) — peut ne pas être disponible sur les noyaux plus anciens
xor  eax, eax
xor  edi, edi
mov  al, 0x69          ; appel système 105
syscall

; Repli : appel système 59 (execve) — le chemin fiable
lea  rdi, [rip+0xf]    ; RDI = pointeur vers "/bin/sh"
xor  esi, esi           ; RSI = NULL (envp)
push 0x3b               ; numéro d'appel système 59
pop  eax
cdq                     ; RDX = NULL (argv)
syscall

; Sortie propre
xor  edi, edi
push 0x3c               ; appel système 60 (exit)
pop  eax
syscall

; Section de données : "/bin/sh\0\0\0"

Ce qu'il fait : Lance /bin/sh sans arguments, héritant des privilèges du processus qui a exécuté su. Si l'exploit s'exécute en tant que root (ou avec des capacités qui accordent à su un accès root), le shell résultant est un shell root.

Ce qu'il ne fait PAS :

  • Pas de shell inversé ni de rappel réseau
  • Aucun mécanisme de persistance (cron, systemd, clé SSH, etc.)
  • Aucun vol d'identifiants ni exfiltration de données
  • Aucun masquage de processus ni anti-forensique

Il s'agit d'une élévation de privilèges directe en un seul coup, cohérente avec un PoC de recherche.


Détails techniques

Constantes Linux clés utilisées

ConstanteValeurObjectif dans l'exploit
AF_PACKET17Famille de sockets de paquets bruts
SOCK_RAW3Type de socket brut
SOL_PNIO279Niveau de protocole non pris en charge (Solaris)
MSG_DONTWAIT0x400Indicateur sendmsg non bloquant

Structure du fichier

root@kitploit:~
copyFail.py
├── hex_to_bytes()         — décodeur de chaîne hexadécimale
├── exploit_splice()       — exploit principal (configuration socket + corruption + splice)
│   ├── Phase 1 : Créer un socket PACKET, lier, setsockopt (SOL_PNIO)
│   ├── Phase 2 : accept() de la connexion
│   ├── Phase 3 : sendmsg() avec des messages ancillaires conçus
│   ├── Phase 4 : pipe() + splice() pour corrompre la mémoire du noyau
│   └── Phase 5 : tentative de recv() (consolide la corruption)
└── Boucle principale :
    ├── Ouvrir /usr/bin/su (lecture seule)
    ├── Décompresser la charge utile intégrée (zlib → ELF de 160 octets)
    ├── Boucle : injecter 4 octets par itération (40 itérations au total)
    └── Exécuter su falsifié → shell root

Pourquoi en lecture seule ?

L'exploit ouvre /usr/bin/su avec O_RDONLY (lecture seule). Il n'a pas besoin d'accès en écriture car la corruption se produit via le cache de pages du noyau — la copie en mémoire du fichier que le noyau utilise avant de vider les modifications sur le disque. L'écriture basée sur splice() contourne entièrement les permissions de fichiers normales, allant directement à la mémoire du noyau.


Détection et atténuation

Indicateurs de compromission

  • Binaire /usr/bin/su modifié (comparer le hash avec le gestionnaire de paquets)
  • Création anormale de sockets PACKET par des processus non root
  • Appels setsockopt() inattendus avec des niveaux de protocole inconnus
  • Appels système splice() sur des descripteurs de fichiers non réguliers

Atténuations

  • Appliquer le correctif du noyau pour cette CVE lorsqu'il est disponible
  • Utiliser sysctl pour restreindre la création de sockets AF_PACKET par les utilisateurs non privilégiés
  • Activer les options de durcissement du noyau (CONFIG_FORTIFY_SOURCE, CONFIG_STACKPROTECTOR)
  • Surveiller l'intégrité des fichiers des binaires critiques (AIDE, OSSEC, Tripwire)

Références

  • PoC original : copyFail.py (tel que distribué)
  • Version annotée : copyFail_cleaned.py (même répertoire)
  • Sous-systèmes du noyau concernés : net/packet/, fs/splice.c, net/core/sock.c

Ce rapport est destiné uniquement à la recherche en sécurité et à l'analyse défensive.

Télécharger l’outil