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é.

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

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
copy-fail-c — Port C multiplateforme de l'exploit Copy Fail Linux LPE (CVE-2026-31431). Divulgué le 2026-04-29 par Theori / Xint. | Kitploit
Outils/GitHubGitHub/tgies/copy-fail-c
Escalade de PrivilègesFrameworks d'ExploitationAnalyse des VulnérabilitésExploitationArticles et RechercheApprentissage et ÉducationDéveloppement de Charges UtilesExploitation de Binaires
GitHubtgies/copy-fail-c

copy-fail-c

Port C multiplateforme de l'exploit Copy Fail Linux LPE (CVE-2026-31431). Divulgué le 2026-04-29 par Theori / Xint.

4401218il y a 2 moisVérifié par Kitploit

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
Voir le dépôt

Copy Fail (CVE-2026-31431) - Portage en C

Anglais (en) ∙ 日本語 (ja) ∙ 简体中文 (zh-cn) ∙ 한국어 (ko) ∙ Русский (ru)

Une réimplémentation en C multiplateforme de l'élévation de privilèges Linux Copy Fail (CVE-2026-31431), divulguée le 29 avril 2026 par Theori / Xint. Voir l'article canonique sur copy.fail pour la description complète de la vulnérabilité, la chronologie et le processus de découverte de Theori.

La preuve de concept publiée est un script Python de 732 octets. Ce portage en C démontre que la même exploitation peut être exprimée en C portable compilable vers n'importe quelle architecture supportée par nolibc, sans blocs hexadécimaux par architecture ni assembleur inline dans le code source du projet.

Auteur de ce portage : Tony Gies [email protected]. Découverte et divulgation originale : Theori / Xint.

Organisation du dépôt

copy-fail-c/
├── exploit.c           le dropper (variante de mutation binaire)
├── exploit-passwd.c    le dropper (variante /etc/passwd avec changement d'UID)
├── vulnerable.c        vérificateur de vulnérabilité non destructif
├── payload.c           le corps qui est déposé (setgid+setuid+execve sh)
├── utils.c, utils.h    primitive partagée de mutation du cache de pages via AF_ALG/splice
├── Makefile            orchestration de compilation
├── nolibc/             importé depuis torvalds/linux tools/include/nolibc
└── README.md           ce fichier

Après make :

├── payload             petit ELF statique, intégré dans le dropper sous forme d'octets
├── payload.o           payload encapsulé en .o relogable par `ld -r -b binary`
├── exploit             dropper, variante de mutation binaire
├── exploit-passwd      dropper, variante /etc/passwd avec changement d'UID
└── vulnerable          vérificateur de vulnérabilité non destructif

exploit.c ouvre le binaire cible en lecture seule, puis pour chaque fenêtre de 4 octets du payload intégré, exécute un déchiffrement AEAD factice via AF_ALG dont l'entrée de texte chiffré est fournie par splice() depuis les pages du cache de pages de la cible. L'optimisation in-place du template authencesn traite les pages source issues de splice à la fois comme entrée de texte chiffré et destination du texte clair, de sorte que le déchiffrement (échoué) a déjà écrasé la page du cache de pages au moment où la vérification d'authentification rejette la requête. Après 4 * N itérations, l'image mise en cache de la cible a été remplacée octet par octet par le payload. L'exécution de la cible via execve() charge les pages mutées ; l'inode sur disque est toujours setuid root, donc le noyau accorde les privilèges root et exécute le payload.

payload.c est du C portable standard : setgid(0); setuid(0); execve("/bin/sh", ...). nolibc fournit _start, les mécanismes d'appel système et les manipulations de registres par architecture.

Une seconde variante, exploit-passwd.c, mute quatre octets du cache de pages de /etc/passwd au lieu de l'image d'un binaire setuid. Elle n'a pas besoin de payload intégré et fonctionne sur les systèmes où la mutation d'un binaire est bloquée, mais sa surface de monétisation est beaucoup plus réduite.

vulnerable.c n'est pas une exploitation. Il crée un testfile local contenant la chaîne init, puis exécute la même primitive patch_chunk() contre le cache de pages de ce fichier pour écraser les octets avec vulnerable. Si le contenu relu correspond, le noyau en cours d'exécution est dans la fenêtre de CVE-2026-31431. L'inode sur disque n'est jamais modifié ; testfile est supprimé à la sortie ; la mutation du cache de pages s'évapore avec lui. S'exécute sans privilèges. Renvoie 100 si vulnérable, 0 si la primitive a fonctionné mais que la mutation n'a pas pris, 2 si la famille de sockets AF_ALG ou le template authencesn est indisponible donc l'état du patch ne peut être déterminé, et 1 pour d'autres erreurs d'exécution.

Compilation

Par défaut (natif pour l'hôte) :

make

Cross-compilation pour aarch64 (ou toute autre architecture Linux pour laquelle une chaîne de cross-compilation est installée) :

make CC=aarch64-linux-gnu-gcc LD=aarch64-linux-gnu-ld

Architectures supportées par nolibc importé (selon l'amont) : x86_64, i386, arm, aarch64, riscv32/64, mips, ppc, s390x, loongarch, m68k, sh, sparc. nolibc se base sur les macros d'architecture du compilateur, donc choisir le bon CC/LD est suffisant.

Prérequis pour la compilation :

  • un compilateur C (cc, gcc, ou toute variante cross)
  • un éditeur de liens supportant ld -r -b binary (binutils ld et lld le font)
  • les en-têtes UAPI du noyau fournissant linux/if_alg.h et <asm/unistd.h> (Debian/Ubuntu : linux-libc-dev ; variantes cross : généralement incluses par le paquet de la chaîne cross)

Les ensembles d'en-têtes antérieurs à Linux 5.6 n'ont pas __kernel_old_time_t ni struct __kernel_old_timespec, utilisés par le nolibc importé. compat.h (inclus de force dans la compilation du payload) les fournit quand ils sont absents, donc un linux-libc-dev plus ancien compile tout de même. Il est sans effet sur les en-têtes 5.6+.

Il n'y a pas de dépendances à des bibliothèques externes. Le payload est compilé en mode freestanding avec nolibc ; le dropper est lié à la libc de l'hôte uniquement pour fprintf et perror.

Choix architecturaux

Quelques petites fonctionnalités de la chaîne de compilation supportent l'essentiel du travail pour garder le code source portable et le payload petit.

nolibc

nolibc/ est le petit remplacement de libc du noyau, basé uniquement sur des en-têtes, importé depuis torvalds/linux tools/include/nolibc/. Il fournit _start, une macro syscall() portable et des wrappers inline d'appels système, avec les conventions de registres par architecture encodées dans nolibc/arch-*.h. Compiler le payload avec -nostdlib -static -ffreestanding -Inolibc produit un petit ELF statique qui appelle directement le noyau sans entraîner le démarrage de glibc, l'initialisation TLS ou la plomberie de stack canary. Résultat, une fois compressé et décapé (les deux ci-dessous) : ~720 octets sur x86_64, ~1,2 Ko sur aarch64, contre ~17 Ko pour le même payload.c lié avec musl-static ou ~700 Ko avec glibc-static.

ld -r -b binary pour l'intégration

Le Makefile transforme le payload compilé en payload.o via ld -r -b binary -o payload.o payload. L'éditeur de liens émet les octets d'entrée verbatim comme la section de données d'un fichier objet relogable et synthétise trois symboles à partir du nom du fichier d'entrée :

_binary_payload_start    adresse du premier octet du payload
_binary_payload_end      adresse après le dernier octet du payload
_binary_payload_size     symbole absolu dont la valeur est la taille en octets

exploit.c déclare les deux premiers comme extern const unsigned char[] et calcule la taille par _binary_payload_end - _binary_payload_start.

-Wl,-N plus max-page-size serré

Le payload est lié statiquement avec -Wl,-N -Wl,-z,max-page-size=0x10, ce qui fusionne .text/.rodata/.data en un seul segment LOAD avec un alignement fichier de 16 octets au lieu de l'alignement par défaut de 4 Ko par segment (aligné sur la page noyau). Cela produit un avertissement "RWX permissions" de ld, qui est seulement informatif – la protection mémoire au moment de l'exécution du payload n'a pas d'importance pour son programme à usage unique. Sans ce drapeau, le même code se lie à ~13 Ko sur x86_64 (surtout du remplissage nul entre segments) ; avec, ~1,3 Ko avant la suppression des en-têtes de section ci-dessous.

Télécharger l’outil