
Eine Bash-Implementierung von copyfail (CVE-2026-31431)
Kein Race. Keine Offsets. Kein vorgefertigtes Binary, dem man blind vertrauen muss.
Eine Bash-Implementierung von CVE-2026-31431 (Copy Fail). Das Skript kompiliert zur Laufzeit inline einen minimalen C-Helfer. Die Bash-Ebene übernimmt die Architekturerkennung, die Dekompression des Payloads und die Zielauswahl; die C-Ebene erledigt die eigentliche Kernel-Interaktion (AF_ALG-Sockets, splice, sendmsg), die Bash allein nicht erreichen kann.
Siehe copy.fail für die vollständige technische Aufschlüsselung.
Der Bug befindet sich in algif_aead, der AF_ALG-AEAD-Socket-Schnittstelle des Kernels. Eine In-Place-Optimierung aus dem Jahr 2017 sorgt dafür, dass Page-Cache-Seiten in der beschreibbaren Ziel-Scatterlist einer authencesn-Entschlüsselungsoperation landen können. Füttert man die Schnittstelle über splice() mit der richtigen Eingabe, erhält man einen deterministischen 4-Byte-Schreibzugriff auf den Page Cache jeder lesbaren Datei, einschließlich setuid-Binaries, die einem nicht gehören.
Überschreibe /usr/bin/su mit Shellcode, 4 Bytes auf einmal, führe es aus, erhalte eine Root-Shell. Kein Race-Fenster, keine kernelspezifischen Symbole, keine Wiederholungsversuche.
chmod +x copyfail.sh
# Check if the system is vulnerable before doing anything
./copyfail.sh -c
# Run the exploit (must be non-root)
./copyfail.sh
# Specify a different setuid target
./copyfail.sh -t /usr/bin/passwd
# List all setuid-root candidates on the system
./copyfail.sh -s
Der Exploit überschreibt nur den Page Cache im Speicher; die Datei auf der Festplatte bleibt unangetastet. Ein Neustart stellt alles wieder her. Wenn du sofort aufräumen möchtest:
# Inside your root shell
/usr/bin/su --version # still works from disk if page cache is evicted
# Or just reboot
Wenn du -t mit etwas anderem als su verwendet hast, gilt dasselbe. Es betrifft nur den Page Cache, die Festplatte ist sauber.
gcc zum Kompilieren des Inline-C-Helferspython3 zum Dekomprimieren des Shellcode-Payloads (Einzeiler, keine Pakete erforderlich)algif_aead, authencesn, hmac, cbcFalls der Algorithmus nicht verfügbar ist:
sudo modprobe algif_aead authencesn hmac cbc
Einige Distributionen liefern einen Block in /etc/modprobe.d/ als temporären Workaround aus. Entferne ihn, falls vorhanden:
sudo rm /etc/modprobe.d/disable-algif{_,-}aead.conf 2>/dev/null
floor: torvalds/linux 72548b093ee3 August 2017, v4.14
(AF_ALG iov_iter rework that introduced
the file-page write primitive via splice
into the AEAD scatterlist)
ceiling: torvalds/linux a664bf3d603d April 2026, mainline
(reverts the 2017 in-place optimization;
source and destination scatterlists are
now separate, page-cache pages can no
longer end up as writable crypto output)
Zwischen diesen beiden Commits: jede größere Distribution, die den Fix nicht zurückportiert hat. Ubuntu, RHEL, SUSE, Amazon Linux und Debian wurden zum Zeitpunkt der Offenlegung alle als verwundbar bestätigt. Distribution-Backports begannen etwa am 29.04.2026 einzutreffen. Um einen bestimmten Kernel zu prüfen, suche im Changelog nach a664bf3d603d (oder dem dazugehörigen Distribution-Backport).
| Architektur | Status |
|---|---|
| x86_64 | ✓ |
| aarch64 | ✓ |
| i386 / i686 | ✓ |
| armv7l | ✓ |
Dauerhaft: Aktualisiere deinen Kernel.
Workaround (blockiert den AF_ALG-Socket; hat keinen Einfluss auf IPsec/XFRM, das die Kernel-Krypto-API direkt verwendet):
echo "install algif_aead /bin/false" | sudo tee /etc/modprobe.d/disable-algif-aead.conf
sudo rmmod algif_aead 2>/dev/null
Container: Füge ein Seccomp-Profil hinzu, das die Erstellung von AF_ALG-Sockets blockiert, und setze allowPrivilegeEscalation: false in deinem Pod-Sicherheitskontext. Dadurch wird no_new_privs aktiviert, was den Kernel daran hindert, setuid-Bits bei execve() zu berücksichtigen.
Die Bash-Version wird bei den Abhängigkeiten nicht gewinnen, aber sie ist ein einzelnes Skript, das du vor der Ausführung vollständig durchlesen kannst. Der C-Helfer wird zur Laufzeit aus einem Heredoc generiert und kompiliert – es gibt keinen Binary-Blob, der separat geprüft werden muss.
Nur für autorisierte Sicherheitstests und Forschung. Führe dies nicht auf Systemen aus, die dir nicht gehören oder für die du keine ausdrückliche schriftliche Erlaubnis zum Testen hast.
| Python | Go | Bash |
|---|
| Abhängigkeit | python3 | keine (statisches Binary) | gcc + python3 |
| Vorgefertigtes Binary | nein | ja | nein |
| Einzelne Datei | ja | nein | ja |
| Kompilierungsschritt | nein | nein | ja (inline, automatisch) |