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