
Lectura fuera de los límites en html2xhtml : CVE-2022-44311
Html2xhtml v1.3 se descubrió que contiene una lectura fuera de los límites en la función static void elm_close(tree_node_t *nodo) en procesador.c. Esta vulnerabilidad permite a los atacantes acceder a archivos sensibles o causar una Denegación de Servicio (DoS) mediante un archivo html manipulado.
CWE-125 Lectura Fuera de los Límites es un tipo de error de software que puede ocurrir al leer datos de la memoria. Esto puede suceder si el programa intenta leer más allá del final de un arreglo, por ejemplo. Las lecturas fuera de los límites pueden provocar bloqueos u otras vulnerabilidades inesperadas, y pueden permitir que un atacante lea información sensible a la que no debería tener acceso.
html2xhtml/src/procesador.c. (GHSA-28fm-qh2h-3mch)Html2xhtml es una herramienta de línea de comandos que convierte archivos HTML a archivos XHTML. Html2xhtml puede generar la salida XHTML compatible con uno de los siguientes tipos de documento: XHTML 1.0 (Transicional, Estricto y Frameset), XHTML 1.1, XHTML Basic y XHTML Mobile Profile.
La vulnerabilidad fue descubierta debido a un error de segfault que ocurrió al usar la opción -t frameset. Un fallo de segmentación o segfault es un tipo específico de error causado al acceder a memoria que no te pertenece. Es un mecanismo de ayuda que evita que corrompas la memoria e introduzcas errores de memoria difíciles de depurar.
Con el uso de Valgrind, una herramienta para encontrar errores de acceso a memoria en memoria heap (memoria que se asigna dinámicamente con new o malloc) en programas C y C++, se depuró el error de segfault y reportó una lectura no válida de tamaño 4 en el caso de prueba:
==1040381== Memcheck, a memory error detector
==1040381== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1040381== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==1040381== Command: ./src/html2xhtml -t frameset report/vuln/id:000000,sig:11,src:001386+001369,time:12081510,execs:2336913,op:splice,rep:16
==1040381==
==1040381== Invalid read of size 4
==1040381== at 0x40E911: elm_close (procesador.c:944)
==1040381== by 0x410617: err_html_struct (procesador.c:1889)
==1040381== by 0x40F20A: err_content_invalid (procesador.c:0)
==1040381== by 0x40F20A: elm_close (procesador.c:959)
==1040381== by 0x40E7C4: saxEndDocument (procesador.c:233)
==1040381== by 0x40DF7A: main (html2xhtml.c:117)
==1040381== Address 0x6f20d4 is not stack'd, malloc'd or (recently) free'd
==1040381==
==1040381==
==1040381== Process terminating with default action of signal 11 (SIGSEGV)
==1040381== Access not within mapped region at address 0x6F20D4
==1040381== at 0x40E911: elm_close (procesador.c:944)
==1040381== by 0x410617: err_html_struct (procesador.c:1889)
==1040381== by 0x40F20A: err_content_invalid (procesador.c:0)
==1040381== by 0x40F20A: elm_close (procesador.c:959)
==1040381== by 0x40E7C4: saxEndDocument (procesador.c:233)
==1040381== by 0x40DF7A: main (html2xhtml.c:117)
==1040381== If you believe this happened as a result of a stack
==1040381== overflow in your program's main thread (unlikely but
==1040381== possible), you can try to increase the size of the
==1040381== main thread stack using the --main-stacksize= flag.
==1040381== The main thread stack size used in this run was 8388608.
==1040381==
==1040381== HEAP SUMMARY:
==1040381== in use at exit: 88,190 bytes in 13 blocks
==1040381== total heap usage: 22 allocs, 9 frees, 2,218,413 bytes allocated
==1040381==
==1040381== LEAK SUMMARY:
==1040381== definitely lost: 0 bytes in 0 blocks
==1040381== indirectly lost: 0 bytes in 0 blocks
==1040381== possibly lost: 0 bytes in 0 blocks
==1040381== still reachable: 88,190 bytes in 13 blocks
==1040381== suppressed: 0 bytes in 0 blocks
==1040381== Rerun with --leak-check=full to see details of leaked memory
==1040381==
==1040381== For lists of detected and suppressed errors, rerun with: -s
==1040381== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
==1040419== Memcheck, a memory error detector
El registro de errores de Valgrind nos llevó a la siguiente función donde ocurrió el segfault:

Se encontró que falta una verificación de tipo en la función. El usuario estaba pasando un nodo de tipo comment en lugar de element a la función y esto resulta en un error de lectura fuera de los límites. Un usuario podría proporcionar un documento malformado con un ELM_PTR(nodo).contenttype[doctype] no válido, resultando en la siguiente comparación en ensamblador:
cmp dword ptr [rbp + rax*4 + 0xc], 4
Los atacantes pueden aprovechar esta vulnerabilidad para leer archivos, memoria o ubicaciones sensibles usando un archivo manipulado.
| Gravedad | Alta 8.1 / 10 |
|---|
| Complejidad del Ataque | Baja |
| Privilegios Requeridos | Ninguno |
| Interacción del Usuario | Requerida |
| Alcance | Sin cambios |
| Confidencialidad | Alta |
| Integridad | Ninguna |
| Disponibilidad | Alta |