Portada
mis comunidades
otras secciones
Hot Potato – Windows Privilege Escalation
"El principio de laicismo vale para todos los aspectos de la vida. Es un principio de libertad y de respeto. Si hay que buscar un sinónimo, sería la libertad. Se opone al proselitismo en el conjunto de los centros escolares, de ahí que se prohíban signos religiosos ostentosos", añadió.
Noviembre de 1991 en Burundi. El Partido para la Liberación del Pueblo Hutu ataca Bujumbura. Mueren centenares de personas. Al norte del país, en Ntita, un médico necesita medicamento que solo puede obtener en Bujumbura. Se salta el toque de queda. Es tiroteado pero consigue escapar con vida: los tiros impactan en el todoterreno y no en su cuerpo. Los militares le roban el dinero que llevaba para los fármacos.
La Tabla de Gilgamesh, una tabilla de arcilla de 3.500 años de antigüedad que relata en escritura cuneiforme la que es considerada como una de las primeras epopeyas de la historia, fue presentada este martes en Bagdad, tras haber sido robada de un museo iraquí en 1991 y recuperada y devuelta por Estados Unidos.
Voy a intentar explicar un poco en que consiste este fallo, en parte traduciendo al español y en parte usando los conocimientos que tengo del tema. Creo que es mucho más facil si abordamos esto en la dirección contraria a como lo explica el artículo (desde el final al principio)
En windows existe una tecnología llamada SMB, que entre otras cosas se utiliza para las carpetas compartidas. Una de las opciones que te da NTLM es poder crear una shell (hay un programa de windows internals llamado psexec que hace esto). Para conseguir esta shell necesitamos poder suministrar unas credenciales, y para eso usaremos un sistema llamado NTLM. NTLM es un protocolo de desafío/respuesta, es decir, que cuando queremos autenticar, el servidor (en este caso el servicio SMB local de la máquina) nos va a hacer una pregunta y tenemos que darle una respuesta que solo es posible calcular conociendo la contraseña. Por lo tanto, podemos abrir una shell con permisos si:
- Obtenemos la contraseña del administrador local o de la cuenta de sistema (una cuenta con aun más privilegios que administrador que usa windows)
- Podemos convencer a alguien que conoce la contraseña que nos de la respuesta al desafío
La primera opción no es factible, pero la segunda si que lo es. De hecho hay algunas limitaciones de seguridad para que no puedas hacer esto en ciertos escenarios, pero el que cubren en este ataque sigue abierto
Como convencemos a alguien para que nos de esa respuesta? Lo más sencillo es coger una petición lícita por parte del sistema que normalmente no pide autenticación y hacerle creer que si la esta pidiendo. Si le damos el mismo desafío que SMB nos esta pidiendo, la respuesta que obtenemos debería ser válida para SMB. El sistema hace automáticamente una serie de peticiones, pero las que son más fáciles de alterar son aquellas de tipo HTTP. Esto es porque las peticiones HTTP no es raro que circulen a través de un proxy, un intermediario que recibe las peticiones y da las respuestas (muy común en entornos empresariales donde de esta forma se puede controlar el tráfico HTTP que hacen los clientes). Ahora bien, hay un problema, para cambiar el proxy que utilizan las operaciones del sistema, tienes que ser administrador, pero si de alguna forma conseguimos cambiarlo, podemos hacer que una operación de sistema vaya a nuestro proxy en lugar del proxy real (o sin proxy), y engañarla para que nos de la respuesta al desafío NTLM. Así que ese es el objetivo a partir de ahora. Operaciones de sistema hay muchas, pero en el ejemplo usan cosas como Windows Update o la actualización de Windows Defender (hay alguna más relacionadas con la cryptoApi de Windows que gestiona los certificados, pero la idea es la misma)
Las aplicaciones de windows tienen dos librerías básicas para realizar peticiones HTTP, conocidas como WinHTTP y Wininet. La configuración de WinHTTP (que incluye el proxy) es única para toda la máquina, mientras que la configuración de la Wininet depende de cada usuario. Por lo tanto, una petición hecha por un servicio del sistema tiene dos opciones:
- Utilizar WinHTTP y el perfil general (prácticamente todas las llamadas de sistema en un windows moderno)
- Utilizar Wininet y el perfil de la cuenta de sistema (NT Authority/SYSTEM) (alguna habrá, pero es raro, y probablemente si le pides autenticación, lo negará)
Aquí es donde el equipo que lo ha hecho sabe que funciona, pero parece que no tiene 100% claro por qué, creo que puedo arrojar algo de luz. Cambiar la configuración de proxy de WinHTTP requiere permisos de administrador, así que nada, no es una opción. Una de las cosas curiosas es que los windows modernos tienen un servicio corriendo que copia la configuración de proxy de la Wininet a Winhttp, por lo que al final, si logramos cambiar la configuración de proxy de wininet, cuando ese servicio lo detecte, acabará cambiando la de Winhttp también. Creo que es por la frecuencia con la que se les debe estar haciendo esta copia de configuración por la que a veces les funciona y otras no
Como podemos cambiar el proxy? Hay una opción en Windows que es configurar el proxy automáticamente, muy util en entornos empresariales, porque sin ella tendríamos que configurar el proxy a mano (bueno, a mano no, hay alternativas, pero esta automática esta ahi). Esto significa que cada cierto tiempo que se hace una petición a la Wininet, esta va a intentar localizar un fichero llamado http://wpad/wpad.dat que incluye la configuración del proxy. Básicamente, intenta ver si hay una máquina llamada wpad de la que el ordenador tenga constancia y si esta ahi, le pide los datos del proxy. Hemos avanzado un paso más, si conseguimos convencer a la máquina que existe alguien llamado wpad en la red y que nosotros controlamos (puede ser la misma máquina en la que estamos), podemos decirle que configuración de proxy utilizar.
Como conseguimos esto? Windows va a tratar de localizar wpad de tres formas distintas. Intenta una y si falla, pasa a la siguiente de la lista:
- Que en un fichero especifico de la maquina (el fichero hosts), aparezca el nombre de wpad y una dirección IP. Esto es muy raro, porque lo tendría que haber puesto un administrador. Si este es el caso, no vamos a poder atacar la máquina
- Que un servidor de DNS nos dé la dirección ip de la máquina wpad
- Que preguntando a lo loco a nuestro "vecindario", alguien sepa de esa máquina y nos responda (NBNS)
Alterar el fichero hosts esta fuera de nuestro control, requiere permisos.
Conseguir que el servidor DNS nos responda con el valor que queremos, también, ya que es una máquina distinta de la red
Que alguien de nuestro vecindario (y una vez más, podemos ser nosotros mismos) nos responda diciendo que la máquina existe, es una posibilidad
Por lo tanto, ahora tenemos tres objetivos:
a) Hacer que la búsqueda en el fichero hosts falle
b) Hacer que la petición DNS a wpad falle
c) Hacer que la petición al vecindario NBNS de el valor para wpad que nosotros queremos
Para conseguir a), nuestra única esperanza es que la entrada no este ahi, pero como decíamos, esa entrada no va a estar ahi el 99%
b) Hacer que la petición DNS falle
Aquí pueden pasar dos cosas. Si el servidor DNS local no tiene una entrada para wpad, ya hemos logrado nuestro objetivo. Pero si el servidor tiene una entrada wpad, tenemos que asegurar que la pregunta falle sin tocar el servidor DNS. Para saber como hacer esto, hay que entender un poco como funciona la comunicación. El mejor ejemplo, es que cuando haces una petición de DNS, estas enviando una carta y esperando una respuesta, pero la dirección que pones en el remitente tiene que ser forzosamente un apartado de correos de tu oficina de correos local (que amablemente ofrece el servicio gratis). Lo interesante, es que el número de apartados de correos disponibles en la oficina es limitado. Si "alguien" (como puede ser nuestro programa atacante), ha alquilado todos los apartados de correos disponibles, la Wininet no puede alquilar uno que poner como remitente, cuando esto pasa, se considera que esta opcion falla y pasa a la alternativa, NBNS), así que b) es fácil de conseguir (es la opción que el articulo dice
disableexhaust false. Quizá hubiera sido más claro si la sintaxis fueraenableexhaust true)Por lo tanto, solo queda c), si logramos que una petición NBNS preguntando por wpad responda lo que nosotros queramos, podemos hacer que el proxy se configure con los valores que queramos, con eso, alterar la petición de una operación del sistema y así conseguir que nos de la respuesta al desafío NTLM que nos lanza SMB.
Bien, para entender como funciona NBNS, digamos que estamos haciendo es gritar a todos los vecinos del barrio "Si alguien conoce a wpad, por favor, que me ponga su dirección en un sobre y la meta en mi buzón". Si el wpad real existe, cuando esto pasa, un puñado de vecinos vendrán y pondrán sobres en el buzón dando su dirección verdadera. La clave aquí es que nuestro programa atacante también puede poner mensajes en ese buzón, por lo que se pone a escribir mensajes a lo loco dicendo que wpad tiene la dirección IP que nos interesa, y no la que ponen los vecinos. Con un poco de suerte, aunque los vecinos estén escribiendo la dirección real de wpad en el buzón, nuestro programa esta poniendo tantos mensajes ahi que los tapa y no son visibles, por lo que cuando Wininet abre el buzón y coge uno, no llega a ver las respuestas reales, solo las falsas que hemos escrito. Hay un pequeño detalle aquí, y es que ese sobre con la dirección de wpad tiene que tener escrito un numero entre 1 y ~65k, pero no importa, porque nuestro programa escribe tantos mensajes tan rápidos que puede escribir uno para cada uno de los 65k números, por lo que objetivo conseguido.
Continuacion en #113