
# Pädagogische Neufassung des Copy-Fail-PoC (CVE-2026-31431) — Linux-Kernel-LPE über algif_aead-In-Place-Krypto + splice()-Page-Cache-Schreibvorgang
Pädagogische Neuaufbereitung des Proof-of-Concept von Theori/Xint für CVE-2026-31431,
eine lokale Privilegieneskalations-Schwachstelle in der algif_aead-Krypto-Socket-Schnittstelle
des Linux-Kernels. Betrifft jeden Mainline-Kernel von 4.14 (Juli 2017)
bis 6.18.21 sowie den stabilen 6.19-Zweig bis 6.19.11.
Nur für Bildungszwecke und autorisierte Sicherheitsforschung. Führen Sie dies NICHT auf Systemen aus, die Ihnen nicht gehören oder für die Sie keine ausdrückliche schriftliche Genehmigung zum Testen haben. Die Ausführung auf einem verwundbaren Host verschafft jedem unprivilegierten lokalen Benutzer sofortigen Root-Zugriff. Die Autoren übernehmen keine Verantwortung für Missbrauch.
Der Linux-Kernel stellt seit Kernel 3.2 über die AF_ALG-Socket-Familie
(<linux/if_alg.h>) eine In-Kernel-Kryptografie-API für Userspace bereit. Userspace
öffnet einen SOCK_SEQPACKET-Socket, bindet ihn an eine Algorithmus-Vorlage (z. B.
"aead" / "authencesn(hmac(sha256),cbc(aes))") und sendet Daten zur
Verschlüsselung oder Entschlüsselung.
Im Jahr 2017 wurde eine Leistungsoptimierung zusammengeführt, die es AEAD-Algorithmen ermöglicht, Daten an Ort und Stelle zu verschlüsseln oder zu entschlüsseln, wenn der Kernel erkennt, dass Quelle und Ziel dieselben zugrunde liegenden Seiten gemeinsam nutzen. Dadurch wird bei jedem Vorgang eine redundante Speicherkopie vermieden.
Die authencesn-Vorlage (die Extended-Sequence-Number-Unterstützung zur
authentifizierten Verschlüsselung hinzufügt) enthält während der Entschlüsselung einen
Scratch-Schreibvorgang: Sie schreibt ESN-Bytes in einen bestimmten Offset innerhalb des
Datenpuffers des Vorgangs, bevor die Authentifizierungsprüfung ausgeführt wird. Wenn die
Quellseiten des Vorgangs über splice() aus dem Page-Cache einer regulären Datei
stammen und die In-Place-Optimierung aktiv ist, geht dieser Scratch-Schreibvorgang
direkt zurück in diese gecachten Seiten.
Da der Page-Cache des Kernels ein gemeinsames Mapping ist — jeder Prozess, der dieselbe Datei öffnet, sieht dieselben physischen Seiten — kann ein unprivilegierter Benutzer:
/usr/bin/su) mit O_RDONLY öffnen.AF_ALG-Operations-Socket splicesen.authencesn-Entschlüsselung auslösen; der ESN-Scratch-Schreibvorgang
beschädigt die Seite an einem kontrollierten Offset mit angreiferkontrollierten Bytes.Off-Host-Integritätsscanner (AIDE, Tripwire, IMA/EVM), die Prüfsummen von On-Disk-Dateien vergleichen, sind für diesen Angriff völlig blind. Der Schreibvorgang verschwindet nach einer Page-Cache-Verdrängung oder einem Neustart und hinterlässt keine forensische Spur auf der Festplatte.
Durch das Zielen auf /usr/bin/su (ein setuid root-Binary) und das Überschreiben
eines Verzweigungsbefehls, der die PAM-Authentifizierungsprüfung schützt, erhält der
Angreifer eine passwortlose Root-Shell.
| Zweig | Erste verwundbare Version | Letzte verwundbare Version | Behoben in |
|---|---|---|---|
| Mainline | 4.14 | 6.18.21 | 6.18.22 |
| 6.19 stable | 6.19.0 | 6.19.11 | 6.19.12 |
| 7.0-rc | 7.0-rc1 | 7.0-rc6 | 7.0-rc7 |
Der Optimierungs-Commit, der den Fehler einführte, landete im 4.14-Entwicklungszyklus
(Juli 2017). Jeder Kernel, der mit CONFIG_CRYPTO_USER_API_AEAD=y und
CONFIG_CRYPTO_AUTHENC=y (beides gängige Standardwerte) in den obigen Bereichen
kompiliert wurde, ist verwundbar.
| Distribution | Mitgelieferter Kernel (ca.) | Gepatcht? |
|---|---|---|
| Debian 12 (Bookworm) | 6.1.x | Ja (Backport) |
| Debian 13 (Trixie) | 6.12.x / 6.14.x | Ja (Backport) |
| Ubuntu 24.04 LTS | 6.8.x | Ja (USN-7xxx) |
| Ubuntu 24.10 | 6.11.x | Ja |
| RHEL 9.x | 5.14.x (rebasiert) | Ja (RHSA) |
| Alpine 3.20 | 6.6.x | Ja (Backport) |
| Arch Linux | Rolling (≥ 6.18.22 jetzt) | Ja |
| Kali Linux 2026.1 | 6.18.12 | Verwundbar |
| Kali Linux 2026.2+ | 6.18.22+ | Behoben |
| Linux Mint 22 | 6.8.x (Ubuntu-Basis) | Ja (Ubuntu USN) |
Überprüfen Sie den Sicherheits-Tracker Ihrer Distribution für den genauen Advisory-Status.
os.splice wurde in Python 3.10 hinzugefügt)/usr/bin/su, weltweit lesbar,
da es setuid ist)# Zeigt, was geschrieben würde, ohne den Kernel zu berühren (sicher):
python3 copy_fail_exploit.py --dry-run
# Patcht den /usr/bin/su-Page-Cache (verwundbarer Kernel erforderlich):
# WARNUNG: verwundbarer Kernel erforderlich — nur auf Systemen verwenden, die Ihnen gehören
python3 copy_fail_exploit.py
# Patcht und eskaliert sofort zu Root:
python3 copy_fail_exploit.py --spawn-shell
# Verwendet ein benutzerdefiniertes Ziel-Binary und Payload:
python3 copy_fail_exploit.py --target /usr/bin/sudo --payload-file ./custom_patch.bin
# Ausführliche Ausgabe (jeden 4-Byte-Schreibvorgang ausgeben):
python3 copy_fail_exploit.py --verbose --dry-run
Standardmäßig ist --spawn-shell aus. Nach dem Patchen gibt das Skript Folgendes aus:
[+] Patch auf Page-Cache von '/usr/bin/su' angewendet (Festplatte unverändert).
Führen Sie `su` aus, um zu eskalieren, oder führen Sie es erneut mit --spawn-shell aus.
Zum Wiederherstellen: echo 3 | sudo tee /proc/sys/vm/drop_caches
Sie müssen dem Shell-Spawn mit --spawn-shell zustimmen. Dies ist beabsichtigt:
Es zwingt Sie, zu verstehen, was der Exploit getan hat, bevor Sie das Ergebnis ausführen.
Einrichten des Primitivs.
Der Exploit öffnet einen AF_ALG-Socket und bindet ihn an die
authencesn(hmac(sha256),cbc(aes))-Vorlage mit einem Dummy-All-Null-Schlüssel. Er
konfiguriert dann die Authentifizierungs-Tag-Größe auf 4 Bytes über ALG_SET_AEAD_AUTHSIZE.
accept() auf dem Kontroll-Socket liefert einen Operations-Socket, der einzelne
Entschlüsselungsanfragen übermitteln kann.
Auslösen des Page-Cache-Schreibvorgangs.
Für jedes 4-Byte-Chunk des Patch-Payloads ruft der Exploit sendmsg() auf dem
Operations-Socket mit gesetztem MSG_MORE auf und übergibt 8 Bytes assoziierte Daten
(AAD): 4 Bytes Füllmaterial gefolgt von den 4 Payload-Bytes. MSG_MORE teilt dem
Kernel mit, den Vorgang zu halten, bis weitere Daten eintreffen. Er erstellt dann eine
Pipe und führt zwei splice()-Aufrufe aus — file_fd → pipe → op_sock — und spendet
die eigenen Page-Cache-Seiten der Datei als Eingabe für den Entschlüsselungsvorgang. Wenn
recv() schließlich aufgerufen wird, führt der Kernel die authencesn-Entschlüsselung aus.
Die In-Place-Optimierung greift (Quelle und Ziel sind dieselben Seiten), und der
ESN-Scratch-Schreibvorgang kopiert unsere Payload-Bytes in die Cache-Seite am
Ziel-Offset. recv() gibt EBADMSG zurück, weil das Authentifizierungs-Tag nicht
verifiziert werden kann — das ist erwartet und harmlos. Der Schreibvorgang ist bereits erfolgt.