
Copy Fail - CVE-2026-31431 - Implémentation C renforcée pour les opérations de redteam et de tests de pénétration autorisés. ⚠️ Avis légal : Cet outil est destiné uniquement à la recherche en sécurité autorisée, aux tests de pénétration autorisés et à l'analyse défensive. Utilisez-le sur des systèmes que vous possédez ou pour lesquels vous avez une autorisation écrite explicite de tester. L'accès non autorisé à des systèmes informatiques est illégal.
Implémentation C durcie pour les opérations d'équipe rouge et de tests de pénétration autorisés.
⚠️ Avis légal : Cet outil est destiné uniquement à la recherche en sécurité autorisée, aux tests de pénétration autorisés et à l'analyse défensive. Utilisez-le uniquement sur des systèmes que vous possédez ou pour lesquels vous avez une autorisation écrite explicite. L'accès non autorisé à des systèmes informatiques est illégal.
🚀 Le développement principal a été déplacé sur GitLab.
Ce dépôt est activement maintenu ici. Pour les problèmes et les contributions, veuillez utiliser GitLab.
Ce projet est un portage C durci et prêt pour la production de l'exploit d'élévation de privilèges local CVE-2026-31431 (« Copy Fail »), initialement divulgué par Theori et Xint le 29 avril 2026.
La preuve de concept originale était écrite en Python et conçue pour une démonstration de recherche. Cette implémentation la transforme en une boîte à outils de niveau équipe rouge avec :
| Attribut | Valeur |
|---|---|
| Date de divulgation | 29 avril 2026 |
| Chercheurs | Theori (Jinoh Kang, Yonghwi Jin, Seunghyun Lee), Xint |
| Article | https://copy.fail/ |
| PoC originale | theori-io/copy-fail-CVE-2026-31431 (Python) |
| Portage C (base) | tgies/copy-fail-c par Tony Gies |
| Noyaux affectés | Linux 4.14 -- 6.14 (avant le commit correctif a664bf3d603d) |
| Sévérité | CVSS 7.8 (Élevée) -- Élévation de privilèges locale |
La vulnérabilité réside dans le sous-système crypto AF_ALG du noyau Linux. Le modèle AEAD authencesn implémente une optimisation en place pour le déchiffrement : lorsque le texte chiffré est fourni via splice() depuis le cache de pages d'un fichier, le noyau réutilise la même page à la fois comme source et comme destination.
Le flux d'attaque :
/usr/bin/su) en lecture seuleauthencesn(hmac(sha256),cbc(aes)) via AF_ALGsplice() depuis le cache de pages du fichier cibleexecve() la cible -- le noyau charge les pages modifiées depuis le cache, accorde les droits setuid-rootPoint clé : L'inode sur le disque n'est jamais modifié. Seul le cache de pages en mémoire est modifié, ce qui rend la détection forensique nettement plus difficile que les exploits traditionnels par écrasement de fichier.
Ce projet étend la recherche originale avec un durcissement orienté équipe rouge à travers neuf modules.
patch_chunk.c)| Fonctionnalité | Original | Notre implémentation |
|---|---|---|
| Gestion des sockets | Nouveau socket par bloc | Réutilisation du socket (~60 % d'appels système en moins) |
| Vérification | Aucune | mmap + memcmp avec réessai automatique (3 tentatives) |
| Écritures parallèles | Séquentielles uniquement | Parallélisme basé sur fork (jusqu'à 16 processus) |
| Codes d'erreur | Succès/échec binaires | Granulaires : 0 = vérifié, 1 = noyau patché, -1 = fatal |
| Allocations tas | malloc dans le chemin chaud | Uniquement sur la pile (pas de gigue d'allocation) |
target_discovery.c)su, sudo, passwd, pkexec, mount, ping, etc./snap (setuid non traditionnel)anti_forensics.c)| Technique | Objectif |
|---|---|
posix_fadvise(POSIX_FADV_DONTNEED) | Éviction du cache de pages par fichier |
echo 3 > /proc/sys/vm/drop_caches | Suppression globale du cache (post-root) |
utimensat() timestomp | Restauration des atime/mtime originaux |
| Autodestruction | Écrasement du binaire dropper avec des zéros avant exec |
| Nettoyage mémoire | Mise à zéro volatile des tampons sensibles |
memfd_exec.c)kworker, anon_inode, eventfd (se fond dans /proc/$pid/fd/)stage1.c)| Canal | Furtivité | Vitesse | Priorité de repli |
|---|---|---|---|
| Intégré | Maximale | Instantané | Dernier (airgap) |
| HTTP direct | Moyenne | <1s | Premier |
| curl/wget système | Faible | 1-3s | Deuxième (support HTTPS) |
| DNS TXT | Élevée | Lent | Troisième (contournement de pare-feu) |
stage2_template.c)SIGUSR1 (déclenchement), SIGUSR2 (statut), SIGTERM (arrêt)[kworker/N:0] dans ps/topproc_hide.c)/proc/$pid/cmdlineSSH_*, AWS_*, TOKEN*, etc.setsid() + setpgid() pour l'indépendance du terminalsignal_trigger.c)| Mode | Comportement | Cas d'utilisation |
|---|---|---|
trigger_oneshot() | Attente → déclenchement → exécution → sortie | Frapper et courir |
trigger_daemon() | Attente → déclenchement → exécution → boucle | Implant persistant |
trigger_auto() | Attente avec repli sur timeout | Opérations sans surveillance |
Attente zéro CPU : sigsuspend() au lieu de boucles de scrutation.
sleep_jitter.c)