Ya son bastantes veces que me tope, en escenarios reales, con ciertas configuraciones en el dominio que permiten a un atacante obtener control sobre ciertos equipos y servidores dadas las siguientes condiciones:
- Se tiene la posibilidad de forzar la autenticación de un usuario o servidor hacia el equipo del atacante.
- Este usuario o servidor tienen privilegios administrativos sobre otro servidor o estación de trabajo.
- La firma de mensajes SMB no es requerida.
Los últimos dos puntos no están bajo control del atacante, son configuraciones que ya vienen definidas en un dominio y un atacante sin los privilegios necesarios, no las puede modificar, sin embargo, el primer punto puede ser ejecutado por el atacante, a través de numerosas técnicas ya documentadas y con sus años de antigüedad, en este post demostrare como se pueden realizar estos ataques de relay a través de distintas técnicas, aprovechando llamadas por RPC a distintos servicios.
Uno de estos escenarios pego bastante fuerte el año pasado, a través de la vulnerabilidad Petit Potam, la cual consiste en abusar una funcionalidad legítima de un servidor ADCS (Active Directory Certificate Services) para solicitar un certificado digital en base64 perteneciente a un controlador de dominio, utilizando este para solicitar un TGT a nombre del DC, con este ticket se pueden ejecutar ciertas acciones personificando a dicho DC, incluyendo la recuperación de su hash en formato NTLM, para luego utilizarlo en un proceso de DCSYNC y obtener el resto de los hashes del dominio interno.
Ahora, en muchos casos vi que se referían a Petit Potam como la obtención del certificado digital a través del ADCS, lo cual en mi opinion, es erróneo, ya que la entrega del certificado digital es el funcionamiento regular del servicio. En mi opinion y según mi experiencia, Petit potam es la vulnerabilidad que permite forzar la autenticación de un equipo de dominio hacia el equipo del atacante, el relay hacia el ADCS y el resto de puntos mencionados son parte de la cadena de explotación, pero no necesariamente de la vulnerabilidad.
Existe una abundancia de recursos sobre la explotación de Petit Potam, por lo que no explicare la vulnerabilidad ni la cadena de explotación como tal, pero lo que si me parece importante explorar es Coerce Authentication.
Como comente, es la capacidad de forzar que un equipo se autentique a otro, utilizando la cuenta de usuario asociada al equipo del dominio interno.
Explicando un poco mas este punto, de manera simplificada, cuando un equipo es asociado al dominio interno, se crea un usuario propio de este equipo, el cual será utilizado para validar si el equipo pertenece o no al dominio interno, si el hostname del equipo es SERVER, el usuario creado será SERVER$.
Estos usuarios pertenecientes a equipos son igual de validos para realizar consultas sobre el dominio interno o autenticarse a sus recursos respectivos, sin embargo, pertenecen a un grupo no privilegiado y su acceso es bastante limitado, pero aun pueden ser definidos como usuarios administradores o con privilegios por ACLs hacia otros objetos del dominio.
En este post, mostrare algunos escenarios que me tope en el trabajo, donde equipos son administradores de otros equipos que no requieren la firma de mensajes SMB y captura de hashes NetNTLMv1 utilizando Responder de un controlador de dominio, para luego utilizar un servicio online con el objetivo de intentar obtener el hash NTLM respectivo.
Configuración del entorno.
Procedemos a configurar nuestro entorno de Active Directory con estas prácticas inseguras.
Usuarios de equipos en dominio administradores de otros equipos
Para simular un entorno ligeramente más realista, crearemos un nuevo grupo en nuestro Active Directory, en mi caso, lo llamare equipos_ti.
Y agregaré como miembros a los equipos SOPORTE01 y TECNOLOGIA01.
Similar a casos anteriores, al querer adicionar equipos, debemos expandir la opción Object Types y marcar la casilla de Computers
Luego agregamos a los dos equipos mencionados.
Una vez agregados los equipos, nos autenticamos a estos y por temas de simplicidad, realizaremos la configuración de manera manual.
En el equipo SOPORTE01
Agregamos al grupo de dominio equipos_ti y al equipo ATENCION01$ a los administradores locales.
En el equipo TECNOLOGIA01.
Agregamos al grupo de dominio equipos_ti a los administradores locales.
Captura de hash NetNTLMv1 del Controlador de dominio.
Por defecto, las últimas versiones de Windows Server tienen esta opción configurada de manera más segura, si se utiliza una versión obsoleta de Windows Server, es posible que se lo tenga configurado de la siguiente manera.
Ejecutamos el comando secpol.msc en el controlador de dominio.
En la ventana, navegamos a la pestaña Local Policies, luego Security Options y buscamos la opción Network Security: LAN Manager authentication level.
Haciendo doble click, modificamos el valor del parámetro a cualquiera de los siguientes valores vulnerables:
- Send LM& NTLM responses
- Send LM& NTLM – use NTLMv2 session security if negotiated
- SendNTLM responses only
En mi caso, seleccione la opción Send LM& NTLM responses.
Le damos OK y procedemos a explotar los vectores respectivos.
Ataque – Captura de hash NetNTLMv1 del controlador de dominio
Para capturar el hash, necesitamos que el controlador de dominio se autentique al equipo del atacante, similar a un caso donde un equipo lista los directorios compartidos de otro equipo en red.
Si bien listar los directorios compartidos de un equipo es una tarea sencilla, se necesita tener una sesión activa en el equipo objetivo.
También se puede utilizar la función pública xp_dirtree o xp_fileexists desde una instancia de MSSQL, pero requiere que el servidor objetivo tenga instalado este software (Entrada futura del blog, utilizando herramientas como PowerUpSQL para movimiento lateral en instancias MSSQL de dominio).
Los dos caminos mencionados anteriormente no son aplicables en el entorno que estamos evaluando, ya que no tenemos una manera de generar una sesión activa sobre el controlador de dominio o MSSQL instalado, por lo que utilizaremos una de las muchas herramientas disponibles de Coerce.
- Printerbug
- DFSCoerce
- ShadowCoerce
- PetitPotam
- Dementor
- Coercer (Utiliza 9 distintos métodos, incluyendo algunos de los mencionados anteriormente)
- Etc.
Existen múltiples herramientas que, a través de llamadas por el protocolo RPC, ocasionan que el equipo objetivo se autentique al equipo del atacante, esta autenticación es realizada por el usuario del equipo de dominio, en el caso del laboratorio, usuario DC01$.
Utilizaremos la herramienta Printerbug, que utiliza el servicio SpoolService, relacionado a impresiones, para forzar la autenticación del equipo objetivo hacia el equipo del atacante.
Para demostrar la diferencia después de haber realizado la configuración mencionada, ejecute Responder con la flag –lm para forzar el downgrade en la comunicación establecida sobre el controlador de dominio sin realizar el cambio detallado anteriormente sobre la política de seguridad local.
Se observa que se captura el hash del controlador de dominio, sin embargo, es del tipo NetNTLMv2, por lo que poder crackear o realizar un ataque de fuerza bruta sobre este es prácticamente imposible, ya que el hash representa la contraseña del usuario DC01$, dicha contraseña es definida por el mismo controlador de dominio y tiene una complejidad ideal (Ejemplo: ^7a1913^0*!@$(@#%)@)61!!$^#@*@!5632472579%#^2871$%3497#@469FVTBang6Q^)
La facilidad de los hashes tipo NetNTLMv1 es que ya existen Rainbow Tables correspondiente al hash NTLM, por lo que es mucho más sencillo convertir un hash NetNTLMv1 a NTLM, debido al protocolo obsoleto inicial.
Luego de realizar la configuración respectiva, se vuelve a forzar la autenticación del controlador de dominio hacia el equipo del atacante, obteniendo su hash NetNTLMv1.
Sin embargo, para poder utilizar el servicio online crack.sh, necesitamos configurar un Challenge con el valor 1122334455667788 en Responder, por lo que se procede a realizar el ajuste en la herramienta.
Modificamos el fichero Responder.conf.
Ya teniendo configurado el challenge, ejecutamos nuevamente Responder y Printerbug.
*Nota: Ya que se capturo el hash del DC01 con un challenge aleatorio, será necesario borrar la base de datos de responder, para que vuelva a capturar el hash respectivo (/usr/share/responder/Responder.db en Kali Linux)
Se captura el hash NetNTLMv1, esta vez con el challenge requerido por la página crack.sh.
Ahora, para poder obtener el hash en formato NTLM, se puede utilizar el servicio online mencionado anteriormente o ejecutar un ataque de fuerza bruta sobre el hash, sin embargo, esta tarea requiere bastante poder computacional y tiempo, dado que las contraseñas de los equipos cambian cada 30 días de manera automática, muchas veces este escenario no es el óptimo, por lo que se utiliza el servicio online.
Accediendo a crack.sh, obtenemos información del formato en el enlace https://crack.sh/netntlm/
En el caso de mi laboratorio, el valor a procesar será
NTHASH:A618A0E8ABB78B19A9B03A2DAFDF92101E833100F217F29C
Se observa que el proceso será gratis debido al hash utilizado.
El proceso puede demorar un par de días, a más tardar, pero usualmente es rápido, ya que yo obtuve el resultado después de 31 segundos de procesamiento.
Una vez obtengamos el resultado, tendremos el hash NTLM del controlador de dominio, el cual puede ser utilizado para realizar un DCSYNC sobre el mismo controlador de dominio.
Confirmando que el hash es válido.
Dumpeando los hashes del dominio interno.
De esta manera, se comprometió el dominio interno utilizando un usuario de dominio de bajos privilegios, un método de Coerce authentication y crackeo de un hash NetNTLMv1.
Ataque – Usuarios de equipos en dominio administradores de otros equipos
En un escenario regular y común, usuarios de dominio son los que tienen privilegios administrativos.
Utilizando Bloodhound, interpretamos este escenario de la siguiente manera.
Observamos que el grupo equipos_ti tiene privilegios administrativos sobre los equipos SOPORTE01 y TECNOLOGIA01.
De la misma manera, observamos los miembros del grupo equipos_ti
Se puede concluir que los equipos SOPORTE01 y TECNOLOGIA01 son administradores de si mismos.
Si queremos buscar este tipo de información en Bloodhound de manera directa, podemos utilizar la siguiente query:
MATCH p = (c1:Computer)-[r1:AdminTo]->(c2:Computer) RETURN p UNION ALL MATCH p = (c3:Computer)-[r2:MemberOf*1..]->(g:Group)-[r3:AdminTo]->(c4:Computer) RETURN p
El resultado es el siguiente:
Entendiendo el gráfico, observamos que existe un vector de ataque a través de los usuarios de equipos en el dominio.
Si llegamos a comprometer el equipo ATENCION01, podemos utilizar el hash del usuario ATENCION01$ para obtener acceso administrativo sobre SOPORTE01, posteriormente, utilizamos el hash del usuario SOPORTE01$ para acceder con privilegio administrativo sobre TECNOLOGIA01 y finalmente utilizar el hash del usuario TECNOLOGIA01$ para obtener control del dominio interno, ya que este usuario es miembro de los administradores de dominio.
Utilizando la herramienta mencionada anteriormente, Coercer, podemos realizar un ataque de Relay.
Acceso a SOPORTE01 desde ATENCION01
Utilizaremos la herramienta ntlmrelayx para realizar el ataque mencionado.
En este caso, apuntamos el relay hacia el servidor soporte01.jsec.local, indicando que cualquier intento de autenticación hacia el equipo del atacante sera reenviado hacia el equipo objetivo.
Forzando la autenticación del equipo atencion01.jsec.local hacia el equipo del atacante.
Observamos que al utilizar Coercer, se validaron múltiples maneras de forzar la autenticación del objetivo al equipo del atacante, teniendo éxito en una de ellas según el resultado obtenido en el relay, ya que fue posible autenticarse al equipo soporte01.jsec.local como el usuario JSEC\ATENCION01$, posteriormente dumpeando los hashes de usuarios locales.
Utilizamos al usuario local IEUser para obtener acceso administrativo al equipo, a través de un ataque Pass the hash.
Obtenemos el hash del usuario ATENCION01$, permitiéndonos utilizarlo para acceder administrativamente a SOPORTE01
Obtenemos el hash del usuario SOPORTE01$ utilizando al usuario ATENCION01$.
Ahora podemos utilizar a SOPORTE01$ para obtener acceso administrativo a TECNOLOGIA01$.
Finalmente, comprometemos el dominio interno utilizando el hash del usuario TECNOLOGIA01$.
Sin embargo, si observamos el gráfico en Bloodhound, observamos que no es necesario realizar el relay desde ATENCION01 hacia SOPORTE01, ya que podemos hacerlo directamente desde el segundo mencionado hacia TECNOLOGIA01.
Obtenemos acceso administrativo a TECNOLOGIA01, dumpeando los hashes de usuarios locales.
Sin embargo, consideremos un escenario donde Pass the hash no es posible (los usuarios locales no están autorizados para autenticarse de manera remota), por lo que estos hashes no nos servirían si no llegamos a crackearlos y tener acceso fisico al equipo respectivo.
Podemos configurar el relay para ejecutar un comando en lugar de dumpear los hashes respectivos.
Desplegamos el relay con la flag -c y especificando el comando respectivo.
De igual manera, en la parte inferior, tenemos un intento de autenticación con el usuario demo, donde observamos que es válido, pero no tiene privilegios administrativos.
Ejecutando el ataque Coerce y el comando respectivo.
Observamos que el comando se ejecuto de manera correcta y el usuario demo obtiene privilegios administrativos sobre TECNOLOGIA01
Ahora podemos usar a demo para obtener el hash NTLM del usuario TECNOLOGIA01 y controlar el dominio, siempre y cuando el equipo tenga estos privilegios.
En caso de que se trate de un equipo regular, sin privilegios, pero con información sensible y no se quieran levantar alertas de creación de usuarios o nuevos usuarios en grupos privilegiados, podemos utilizar el relay para desplegar un proxy SOCKS4 y utilizar el intento de autenticación con otras herramientas.
En este caso, utilizaremos Printerbug para forzar una única vez la autenticación del equipo objetivo hacia el atacante, en lugar de 9 veces con Coercer.
Se recomienda utilizar direcciones IP en lugar de hostnames para establecer el proxy, ya que al intentar utilizar el proxy con un hostname, se intentara realizar la resolución del hostname a través de este y fallará, ya que solo se tiene una ruta para el puerto 445, no al puerto 53.
Para listar las conexiones activas, escribimos socks
Observamos que tenemos una sesión activa sobre el equipo 192.168.64.212 con el usuario JSEC/SOPORTE01$ por el puerto 445 con privilegios de administrador (AdminStatus TRUE)
Ahora podemos utilizar proxychains para utilizar esta conexión y los privilegios del usuario SOPORTE01$ para acceder al equipo TECNOLOGIA01 por el protocolo SMB.
Observamos que tenemos acceso administrativo al equipo TECNOLOGIA01, ya que por SMB podemos navegar por el directorio C$, si bien se observa en la captura que se solicita la contraseña, podemos dejarla vacía, ya que se utilizará la sesión almacenada en el relay.
Este tipo de vectores son un poco raros en escenarios reales, sin embargo, yo me topé múltiples veces con este tipo de vectores, especialmente este último, por lo que considero que es importante documentar una de las maneras de explotar estos vectores.
Espero que sea de ayuda!