jueves, 26 de julio de 2018

Vulnerabilidad de 2007 permite escalar privilegios en Solaris

Investigadores de SpiderLabs, el equipo élite de seguridad de Trustwave, han descubierto que una vulnerabilidad de Solaris parcheada hace 9 años no fue totalmente mitigada y todavía se puede escalar privilegios





Un usuario no privilegiado puede ejecutar código en un contexto privilegiado, permitiendo el control total del sistema operativo. Este es el resumen de la vulnerabilidad descubierta en 2007 y publicada en 2009 en la conferencia CanSecWest. El mismo año de su publicación se parcheó, pero investigadores de Trustwave han encontrado resquicios en el parche por donde meterse, y poder seguir explotando la vulnerabilidad. Esta "nueva" vulnerabilidad tiene asignado el identificador CVE-2018-2892.

Si bien la explotación de vulnerabilidades, o exploiting, es un campo que en los últimos años se ha complicado bastante, la explotación de esta vulnerabilidad en concreto no es complicada de entender. Especialmente porque no parece haber protecciones genéricas contra exploiting por parte del sistema operativo (o al menos en la entrada del blog de SpiderLabs no se mencionan). La vulnerabilidad se encuentra en un manejador de ioctl, esto es, una parte de un controlador (driver) que recibe peticiones de aplicaciones posiblemente no privilegiadas. Como en la mayoría de los sistemas operativos para PC, los controladores corren en contexto privilegiado. Lo que tenemos entonces es que recibimos una petición desde el lado no privilegiado, y la manejamos en el lado privilegiado. Si el manejo es robusto, no hay problema. Si el manejo es débil... Vulnerabilidad.

En la vulnerabilidad original (antes de parchear), el error es flagrante. En el manejador de ioctl se usan directamente dos argumentos que vienen del lado no privilegiado: uno que se usa para indicar dónde escribir en memoria privilegiada, y otro para indicar el tamaño a escribir. Esos dos argumentos son pasados a una función que se encarga de copiar memoria del lado no privilegiado al privilegiado, y junto con un tercer argumento que especifica el contenido a copiar, tenemos la forma de escribir lo que queramos (tercer argumento y segundo especificando el tamaño) donde queramos (primer argumento).


En la llamada a 'copyin', 'uap->addr' sería nuestro tercer argumento, y los otros dos, el primero y el segundo respectivamente


Se entiende que el tercer argumento (lo que se copia) aun siendo controlable por el usuario no permite explotación por sí solo si se copia donde se debe, pero si podemos controlar dónde se copia, podemos hacer que sobreescriba código crítico del lado privilegiado y nos permite ejecutar código arbitrario en ese contexto. El parche se antoja sencillo entonces: vale con controlar que el primer argumento no permita escribir fuera del tiesto, y que el segundo argumento no permita escribir más de la cuenta. Y en eso consistió el parche de 2009.

Por desgracia, la comprobación del segundo parámetro es incompleta. Por definición, el segundo parámetro es de tipo 'int', esto es, un valor numérico que puede ser positivo o negativo. Y la comprobación introducida por el parche de 2009 sólo comprueba que no sea mayor de un cierto número positivo, no comprobando si es negativo. ¿Qué problema plantea esto? Que el segundo argumento indica en qué dirección escribir, pero de forma relativa. Existe una dirección fija en memoria, y el segundo argumento indica a qué distancia de esta dirección fija escribimos. Como se controla que el valor positivo no exceda cierto límite, no es posible salirse del tiesto por arriba, pero como el valor negativo no se controla, pues te puedes salir del tiesto por abajo...

Cabe preguntarse por qué una vulnerabilidad tan obvia termina en un punto tan delicado del sistema. Una posible respuesta se encuentra en el código fuente, donde se ve que el tipo de petición que nos lleva al código vulnerable es un tipo de petición usada con propósitos de prueba. Y es que el código escrito con este propósito es usado por los mismos desarrolladores para hacer pruebas de forma rápida y no debe ser usado por el usuario final, con lo que se programa de forma rápida y sin tener la seguridad en mente.




Finalmente, indicamos que Oracle ha publicado un parche para solucionar este problema (esperemos que definitivamente). Un parche sacado apenas hace una semana, en el que se corrige esta vulnerabilidad para las últimas versiones de Solaris 10 y 11. Para su explotación es necesario que esté configurado el módulo Sun StorageTek Availability Suite, ya que el manejador ioctl pertenece a éste.




Carlos Ledesma
@Ravenons


Más información: