
CTF-задача, эксплуатирующая переполнение кучи в png_image_finish_read библиотеки libpng для перезаписи указателя на функцию и запуска оболочки, с скриптами сборки и генератором эксплойтов.
Этот челлендж основан на реальной уязвимости переполнения буфера в libpng (конкретно, в упрощённом API png_image_finish_read при обработке 16-битных чересстрочных изображений).
Вам предоставлен уязвимый бинарный файл victim, который использует статически слинкованную уязвимую версию libpng. Приложение считывает PNG-файл с именем exploit.png в буфер.
Ваша задача — создать вредоносный PNG-файл, который вызывает переполнение кучи для перезаписи указателя на функцию в структуре Logger (расположенной непосредственно после буфера изображения), перенаправляя выполнение на функцию win() для запуска оболочки.
Необходимые компоненты: gcc, make, python3, git, autoconf, automake, libtool.
Клонируйте репозиторий:
git clone --recursive https://github.com/bohemian-miser/CVE-2025-65018_Exploit_Challenge.git
cd CVE-2025-65018_Exploit_Challenge
Соберите челлендж (включая уязвимую libpng):
./build.sh
Этот скрипт:
libpng для включения уязвимости.libpng.victim.Уязвимость заключается в том, как libpng обрабатывает чересстрочные изображения при преобразовании из 16-битного входа в 8-битный выход.
PNG_FORMAT_RGBA). libpng выделяет буфер размером, достаточным для 8-битных данных.png_combine_row некорректно записывает данные, используя 16-битную глубину цвета входных данных в выходной буфер.Бинарный файл содержит вспомогательную функцию win(), которая вызывает execl("/bin/sh", ...). Нам нужен её адрес. Поскольку бинарник скомпилирован с флагом -no-pie, адреса статичны.
nm victim | grep win
# Вывод: 00000000004013e0 T win
Целевой адрес: 0x4013e0
solve.py)Нам нужно создать корректный PNG, который:
IHDR), указывающий 16-битную глубину.win).Скрипт solve.py делает следующее:
Logger (оно составляет 4096 байт от начала буфера).win в данные пикселей последней строки.IDAT.Структура полезной нагрузки:
Адрес win 0x4013e0 (Little Endian: E0 13 40 00 ...) должен быть закодирован в 16-битных RGB-пикселях.
Создайте вредоносный PNG:
python3 solve.py 4013e0
Это создаст exploit.png.
Запустите victim:
./victim
Ожидаемый вывод:
[*] 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...
$
Чтобы увидеть переполнение в действии, можно использовать GDB.
1. Установите точку останова перед уязвимым вызовом:
break 62
run
2. Наблюдайте за перезаписью:
Структура Logger находится на смещении 4096. Наблюдаем за целевым указателем на функцию.
print &ctx.logger.log_func
# $1 = (void (**)(const char *)) 0x7fffffffc8f0
watch *0x7fffffffc8f0
continue
3. Срабатывание:
GDB остановится, когда png_combine_row запишет в указатель функции.
Hardware watchpoint 2: *0x7fffffffc8f0
Old value = 4199366 (0x4013c6 <normal_log>)
New value = 4199392 (0x4013e0 <win>)
0x00007ffff7e024d9 in __memcpy_avx_unaligned_erms ()
Это подтверждает, что libpng перезаписал наш указатель адресом win!
victim.c: Исходный код уязвимого приложения.solve.py: Генератор эксплойта.libpng-src/: Исходный код libpng (v1.6.37).build.sh: Скрипт для компиляции всего.Makefile: Система сборки для бинарного файла victim.