20 de septiembre de 2018

Denegación de servicio y revelación de información en FreeBSD

Una vulnerabilidad en el procesador del formato ELF en el cargador de ejecutables permite forzar el apagado del sistema y extraer información del espacio de memoria del núcleo
Denegación de servicio y revelación de información sensible si puedes correr un ejecutable en la máquina. Ese es el impacto de la última vulnerabilidad reportada en FreeBSD, vulnerabilidad que se puede explotar a través de la ejecución de un ejecutable ELF especialmente diseñado. El código responsable de cargar los ejecutables en memoria es un código especialmente sensible, debido a la cantidad de veces que es llamado por el sistema operativo y a tener que tratar en el núcleo con datos que provienen del usuario.
Lo cierto es que la mayoría del código útil cumple la última condición y procesa en el núcleo datos que vienen del usuario. El problema real es la complejidad de los datos a procesar. Como ejemplo contrario al que nos ocupa, podemos pensar en una llamada al sistema que escribe datos a un archivo. Simplificando, esa llamada al sistema tendría tres argumentos: la ruta del archivo, los datos a escribir y la longitud de estos datos. Los datos a escribir no tienen complejidad alguna para ser procesados: pueden contener cualquier cosa, y se volcarán directamente al archivo. Lo único que debería respetarse es que la longitud de los datos fuese correcta, pero si no lo es, tampoco pasa nada. El sistema operativo volcará más datos de los reales, cogiendo del siguiente trozo de memoria, o llegando a cerrar el proceso que llama si por especificar mal la longitud termina leyendo memoria a la que no tiene acceso.
El último argumento que nos queda es la ruta del archivo. Una ruta de un archivo tiene un formato relativamente sencillo, una serie de nombres separados por barras. Hay algunos caracteres que no pueden contener, así como otros caracteres que pueden dar problemas en ciertos sistemas de archivos, pero es sencillo saber si una ruta de archivo está bien formada y extraer la información que necesitemos de ésta. Otro cantar es el tema que nos ocupa, el procesamiento del formato ELF en los ejecutables:
Al final, el procesamiento de una estructura de datos es similar al procesamiento de lenguajes de programación (parsing), en el sentido de que ambos tienen una estructura predefinida y una lista de construcciones permitida. Y el problema de muchos formatos de archivo, incluido el formato ELF, es que se equiparan a una categoría de lenguajes difíciles de procesar. Por tanto, la complejidad del código para procesarlos aumenta, aumentando también la posibilidad de que exista un fallo de seguridad en el código. Hay publicaciones científicas con proposiciones para simplificar este tipo de formatos sin perder expresividad, como ésta, pero lo cierto es que lo ideal es intentar simplificar lo máximo posible las estructura de datos. De esta forma, se simplificaría el código que las procesa, y los fallos de seguridad serían mucho menos frecuentes.
Pero como siempre, la seguridad aquí se enfrenta a la necesidad de retrocompatibilidad y diseño fácil (que no es lo mismo que el resultado del diseño sea complejo). Tenemos que recordar que la seguridad es un compromiso, y hacer algo seguro al 100% es hacerlo inútil o excesivamente costoso.
Más información:
·         FreeBSD-SA-18:12.elf - Improper ELF header parsing https://www.freebsd.org/security/advisories/FreeBSD-SA-18:12.elf.asc
·         Occupy Babel! - LANGSEC explained in a few slogans http://langsec.org/occupy/
·         Context Parsing (Not Only) of the Object-File-Format Description Language http://elib.mi.sanu.ac.rs/files/journals/csis/28/100408.pdf
Fuente: Hispasec