
Copy Fail - CVE-2026-31431 - Gehärtete C-Implementierung für Redteam- und autorisierte Penetrationstest-Operationen. ⚠️ Rechtlicher Hinweis: Dieses Tool ist ausschließlich für autorisierte Sicherheitsforschung, autorisierte Penetrationstests und defensive Analysen bestimmt. Verwenden Sie es nur auf Systemen, die Ihnen gehören oder für die Sie eine ausdrückliche schriftliche Erlaubnis zum Testen haben. Unbefugter Zugriff auf Computersysteme ist illegal.
Gehärtete C-Implementierung für Redteam-Operationen und autorisierte Penetrationstests.
⚠️ Rechtlicher Hinweis: Dieses Tool ist ausschließlich für autorisierte Sicherheitsforschung, autorisierte Penetrationstests und defensive Analysen bestimmt. Verwenden Sie es nur auf Systemen, die Ihnen gehören oder für die Sie eine ausdrückliche schriftliche Genehmigung zum Testen haben. Unautorisierter Zugriff auf Computersysteme ist illegal.
🚀 Die primäre Entwicklung wurde zu GitLab verlegt.
Dieses Repository wird hier aktiv weiterentwickelt. Für Issues und Beiträge nutzen Sie bitte GitLab.
Dieses Projekt ist eine gehärtete, produktionsreife C-Portierung des CVE-2026-31431 ("Copy Fail") Local Privilege Escalation Exploits, der ursprünglich von Theori und Xint am 29. April 2026 veröffentlicht wurde.
Der ursprüngliche Proof-of-Concept war in Python geschrieben und für Forschungsdemonstrationen ausgelegt. Diese Implementierung wandelt ihn in ein Redteam-taugliches Toolkit um, mit:
| Attribut | Wert |
|---|---|
| Bekanntgabedatum | 29. April 2026 |
| Forscher | Theori (Jinoh Kang, Yonghwi Jin, Seunghyun Lee), Xint |
| Writeup | https://copy.fail/ |
| Original PoC | theori-io/copy-fail-CVE-2026-31431 (Python) |
| C Port (Basis) | tgies/copy-fail-c von Tony Gies |
| Betroffene Kernel | Linux 4.14 – 6.14 (vor Fix-Commit a664bf3d603d) |
| Schweregrad | CVSS 7.8 (Hoch) – Lokale Privilegieneskalation |
Die Schwachstelle befindet sich im AF_ALG-Krypto-Subsystem des Linux-Kernels. Die AEAD-Vorlage authencesn implementiert eine In-Place-Optimierung für die Entschlüsselung: Wenn der Chiffretext über splice() aus dem Page-Cache einer Datei geliefert wird, verwendet der Kernel dieselbe Seite sowohl als Quelle als auch als Ziel.
Der Angriffsablauf:
/usr/bin/su) schreibgeschützt öffnenAF_ALG eine authencesn(hmac(sha256),cbc(aes))-AEAD-Operation einrichtensplice() aus dem Page-Cache der Zieldatei bereitstellenexecve() auf das Ziel ausführen – der Kernel lädt mutierte Seiten aus dem Cache und gewährt setuid-root-BerechtigungenKernpunkt: Der Inode auf der Festplatte wird niemals verändert. Nur der In-Memory-Page-Cache wird mutiert, was die forensische Erkennung deutlich erschwert als bei herkömmlichen Dateiüberschreib-Exploits.
Dieses Projekt erweitert die ursprüngliche Forschung um Redteam-orientierte Härtungen in neun Modulen.
patch_chunk.c)| Merkmal | Original | Unsere Implementierung |
|---|---|---|
| Socket-Verwaltung | Neuer Socket pro Chunk | Socket-Wiederverwendung (~60% weniger Syscalls) |
| Verifikation | Keine | mmap + memcmp mit automatischem Wiederholungsversuch (3 Versuche) |
| Parallele Schreibvorgänge | Nur sequentiell | Fork-basiert parallel (bis zu 16 Prozesse) |
| Fehlercodes | Binär Erfolg/Fehlschlag | Granular: 0=verifiziert, 1=gepatchter Kernel, -1=schwerwiegend |
| Heap-Allokationen | malloc im heißen Pfad | Nur Stack (kein Allokations-Jitter) |
target_discovery.c)su, sudo, passwd, pkexec, mount, ping, etc./snap (nicht-traditionelle setuid)anti_forensics.c)| Technik | Zweck |
|---|---|
posix_fadvise(POSIX_FADV_DONTNEED) | Pro-Datei Page-Cache-Räumung |
echo 3 > /proc/sys/vm/drop_caches | Globaler Cache-Drop (nach Root) |
utimensat() Timestomp | Ursprüngliche atime/mtime wiederherstellen |
| Selbstzerstörung | Dropper-Binärdatei vor exec mit Nullen überschreiben |
| Speicherbereinigung | volatile-Nullung sensitiver Puffer |
memfd_exec.c)kworker, anon_inode, eventfd (fügt sich in /proc/$pid/fd/ ein)stage1.c)| Kanal | Tarnung | Geschwindigkeit | Fallback-Priorität |
|---|---|---|---|
| Eingebettet | Maximal | Sofort | Letzter (Airgap) |
| HTTP direkt | Mittel | <1s | Erster |
| System curl/wget | Niedrig | 1-3s | Zweiter (HTTPS-Support) |
| DNS TXT | Hoch | Langsam | Dritter (Firewall-Bypass) |
stage2_template.c)SIGUSR1 (auslösen), SIGUSR2 (Status), SIGTERM (Herunterfahren)[kworker/N:0] in ps/topproc_hide.c)/proc/$pid/cmdlineSSH_*, AWS_*, TOKEN*, etc.setsid() + setpgid() für Terminalunabhängigkeitsignal_trigger.c)| Modus | Verhalten | Einsatzfall |
|---|---|---|
trigger_oneshot() | Schlafen → auslösen → ausführen → beenden | Hit-and-Run |
trigger_daemon() | Schlafen → auslösen → ausführen → Schleife | Persistierendes Implantat |
trigger_auto() | Schlafen mit Timeout-Fallback | Unbeaufsichtigte Operationen |
Null-CPU-Warten: sigsuspend() anstelle von Polling-Schleifen.
sleep_jitter.c)getrandom(2), /dev/urandom, rdtsc-Fallbacksleep_scheduled() hält das durchschnittliche Intervall trotz Jitter eincheck_sandbox_acceleration() erkennt gepatchtes sleep()