Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
CVE-2023-52356-libtiff-analysis — Анализ первопричины и проверка патча для CVE-2023-52356 в libtiff с использованием AddressSanitizer и GDB. | Kitploit
Инструменты/GitHubGitHub/yardenbenita/cve-2023-52356-libtiff-analysis
Анализ уязвимостейОтладчикиАнализ Бинарных ФайловСтатьи и ИсследованияОбучение и Образование
GitHubyardenbenita/cve-2023-52356-libtiff-analysis

CVE-2023-52356-libtiff-analysis

Анализ первопричины и проверка патча для CVE-2023-52356 в libtiff с использованием AddressSanitizer и GDB.

Репозиторий
12 ч 52 мин назадЕщё не проверено

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

CVE-2023-52356 – Анализ TIFFReadRGBATileExt в libtiff

Обзор

В этом лабораторном анализе рассматривается CVE-2023-52356 в libtiff, с акцентом на поведение TIFFReadRGBATileExt при получении координат изображения, выходящих за допустимые границы.

Анализ включает воспроизведение исходного сбоя, отладку с помощью AddressSanitizer и GDB, анализ первопричины, изучение исправления в апстриме, анализ исходного репро-файла и проверку исправленной версии.

Тестовое окружение

  • Цель: libtiff
  • Уязвимый коммит: 4d0329a4
  • Исправляющий коммит: 51558511
  • Триггерный файл: triger_input_47
  • Инструменты: Clang, AddressSanitizer, GDB, CMake

Воспроизведение сбоя

Исходный репро-файл был скомпилирован против уязвимой сборки libtiff с включённым AddressSanitizer.

Репро-файл был запущен с предоставленным триггерным файлом:

root@kitploit:~
LD_LIBRARY_PATH="$PWD/libtiff/build-asan/libtiff" ./poc triger_input_47

Выполнение воспроизвело ошибку сегментации, вызванную недопустимым чтением памяти. Трассировка стека AddressSanitizer выявила сбой во время операции memmove, вызванной из TIFFReadRGBATileExt.

Анализ первопричины

С помощью GDB условие сбоя было воспроизведено со следующими значениями во время выполнения:

root@kitploit:~
row = 34
img.height = 33
tile_ysize = 1

Затем выполнялся уязвимый код:

root@kitploit:~
read_ysize = img.height - row;

При наблюдаемых значениях это вычисление выглядит так:

root@kitploit:~
33 - 34 = -1

Поскольку read_ysize является беззнаковым, результат был свёрнут до:

root@kitploit:~
read_ysize = 4294967295

что соответствует UINT32_MAX.

Значение read_ysize впоследствии использовалось в вычислении указателя источника для memmove.

Непосредственно перед сбойным memmove GDB показал:

root@kitploit:~
read_ysize = 4294967295
read_xsize = 1
tile_ysize = 1
tile_xsize = 1
i_row = 0
raster = 0x7d0ff67e2d40

Указатель назначения вычислился как:

root@kitploit:~
0x7d0ff67e2d40

что являлось началом буфера raster.

Указатель источника вычислился как:

root@kitploit:~
0x7d13f67e2d38

Вычисленный указатель источника находился на 17179869176 байт, примерно 16 ГиБ, за пределами начала буфера raster.

Выполнение memmove в GDB привело к:

root@kitploit:~
SIGSEGV, Segmentation fault

Трассировка стека показала следующий путь сбоя:

root@kitploit:~
__sanitizer_internal_memmove
__asan_memmove
TIFFReadRGBATileExt at tif_getimage.c:3345
LLVMFuzzerTestOneInput at poc.cc:61

Это подтверждает, что беззнаковое переполнение в read_ysize привело к смещению источника за пределы допустимого диапазона. Полученный недопустимый указатель источника затем использовался memmove, что вызвало недопустимое чтение памяти и ошибку сегментации.

Анализ исправления и проверка исправленной версии

Исправление в апстриме добавило явную проверку границ перед уязвимым вычислением read_ysize:

root@kitploit:~
if (col >= img.width || row >= img.height)
{
    TIFFErrorExtR(tif, TIFFFileName(tif),
                  "Invalid row/col passed to TIFFReadRGBATile().");
    TIFFRGBAImageEnd(&img);
    return (0);
}

С помощью GDB в исправленной версии были получены следующие значения во время выполнения:

root@kitploit:~
row = 34
img.height = 33
col = 0
img.width = 2047

Для этих значений новое условие проверки принимает значение true, поскольку:

root@kitploit:~
row >= img.height
34 >= 33

Таким образом, функция сообщила:

root@kitploit:~
Invalid row/col passed to TIFFReadRGBATile()

и вернула 0.

В результате выполнение не достигло уязвимого вычисления:

root@kitploit:~
read_ysize = img.height - row;

Это предотвращает беззнаковое переполнение, наблюдаемое в уязвимой версии, и не позволяет недопустимому значению использоваться в последующем вычислении указателя источника для memmove.

Анализ репро-файла и предусловия

Исходный репро-файл некорректно вычисляет количество тайлов вдоль оси Y.

Соответствующий код передаёт возвращаемое значение TIFFGetField() напрямую как координату Y в TIFFComputeTile():

root@kitploit:~
TIFFComputeTile(
    in_tif,
    0,
    TIFFGetField(in_tif, TIFFTAG_IMAGELENGTH, &tile_height),
    0,
    0)

С помощью GDB было установлено, что tile_height содержит:

root@kitploit:~
tile_height = 33

Однако TIFFGetField() вернул:

root@kitploit:~
1

Возвращаемое значение указывает на успех; это не высота изображения. Поэтому вызов фактически становится:

root@kitploit:~
TIFFComputeTile(in_tif, 0, 1, 0, 0)

Для этого TIFF GDB показал, что этот вызов возвращает:

root@kitploit:~
2047

Это значение является индексом тайла, а не количеством тайлов вдоль оси Y.

Затем исходный репро-файл использовал это значение в своём вычислении num_tiles_y, что привело к:

root@kitploit:~
num_tiles_y = 63

Однако размеры изображения и тайла составляют:

root@kitploit:~
image_width  = 2047
image_height = 33
tile_width   = 1
tile_height  = 1

Следовательно, правильное количество тайлов вдоль оси Y равно:

root@kitploit:~
num_tiles_y = 33

Некорректное значение 63 приводит к тому, что цикл выполняется со значениями Y от 0 до 62, хотя высота изображения равна 33, а допустимые координаты Y находятся только в диапазоне от 0 до 32.

Это позволяет передать недопустимое значение, такое как:

root@kitploit:~
row = 34

в TIFFReadRGBATileExt.

Уязвимая версия libtiff не отклоняла эту координату за пределами допустимого диапазона перед выполнением беззнакового вычисления img.height - row. Это позволило недопустимому входному значению API, сгенерированному репро-файлом, превратиться в отказ безопасности памяти.

Предоставленный сопровождающим исправленный репро-файл вычисляет количество тайлов напрямую из размеров изображения и тайла.

Для того же TIFF исправленное вычисление даёт:

root@kitploit:~
num_tiles_x = 2047
num_tiles_y = 33

Исправленный репро-файл был протестирован против той же уязвимой сборки libtiff и того же триггерного файла.

Программа завершилась со статусом 0, и ни AddressSanitizer, ни отчёт о SIGSEGV не были получены.

Это подтверждает наблюдение сопровождающего о том, что исходный репро-файл содержит некорректное вычисление количества тайлов. Однако уязвимая версия libtiff по-прежнему не имела защитной проверки строк и столбцов, что позволяло недопустимым координатам API приводить к отказу безопасности памяти.

Сводка проверки

Репро-файлВерсия libtiffРезультат
Исходный PoCУязвимая (4d0329a4)Недопустимое чтение и SIGSEGV в memmove
Исправленный репро-файлУязвимая (4d0329a4)Статус выхода 0, нет ASan/SEGV
Исходный PoCИсправленная (51558511)Недопустимые row/col отклонены, нет ASan/SEGV

Заключение

Сбой в TIFFReadRGBATileExt происходит, когда координата изображения за пределами допустимого диапазона достигает уязвимой реализации libtiff.

В исходном репро-файле некорректное вычисление количества тайлов приводит к тому, что num_tiles_y вычисляется как 63 вместо правильного значения 33. В результате репро-файл может передать строку за пределами допустимого диапазона изображения в TIFFReadRGBATileExt.

В уязвимой версии libtiff аргументы строки и столбца не проверялись перед вычислением:

root@kitploit:~
read_ysize = img.height - row;

Для воспроизведённого случая row было 34, а img.height — 33. Поскольку read_ysize является беззнаковым, вычитание переполнилось до UINT32_MAX. Это значение впоследствии использовалось в вычислении указателя источника для memmove, что привело к недопустимому чтению памяти и ошибке сегментации.

Исправление в апстриме добавляет явную проверку границ строк и столбцов перед этим вычислением. Тестирование исправленной сборки подтвердило, что та же недопустимая координата отклоняется до того, как могут произойти переполнение и memmove.

Предоставленный сопровождающим исправленный репро-файл также был протестирован против уязвимой сборки с использованием того же файла TIFF. Он вычислил правильное количество тайлов и завершился без отчёта AddressSanitizer или SIGSEGV.

Таким образом, данный анализ не устанавливает, что сам файл TIFF вызывает отказ безопасности памяти при корректном использовании API. Исходный репро-файл содержит некорректное вычисление количества тайлов, в то время как историческая реализация libtiff не имела защитной проверки границ и позволяла результирующему недопустимому входному значению API превращаться в отказ безопасности памяти.

Скачать инструмент