miércoles, 26 de septiembre de 2012

Relaying SSH con UDP

Como ya sabéis algunos, me encuentro impartiendo en estos momentos curso del SANS Institute SEC-560: Network Penetration Testing & Ethical Hacking. Durante el transcurso de las clases, mientras veíamos la parte de pivoting, comentábamos que, en ocasiones, todos los puertos TCP pueden estar cerrados de salida, lo cual dificulta hacer el pivoting, aunque no lo imposibilita.

Como una de las posibles soluciones a esta situación está que en muchas empresas existen reglas para permitir la realización de peticiones DNS hacia Internet. Estas peticiones emplean el puerto 53/UDP, por lo que vamos a poder utilizar este puerto para realizar una conexión inversa y realizar el pivoting. En realidad, un relay de puertos mediante UDP es (muy) levemente distinto a un relay de puertos puramente TCP, como el que vimos hace ya tiempo AQUÍ (si alguien no domina este concepto, recomiendo su lectura previa a este post). Sin embargo, he visto en ocasiones gente que ha publicado herramientas específicas para hacer relay empleando puertos de salida UDP, quizá porque no se han parado a analizar profundamente la potencia que herramientas como NetCat nos ofrece:

$ nc -h
usage: nc [-46CDdhklnrtUuvz] [-b boundif] [-i interval] [-p source_port]
 [-s source_ip_address] [-w timeout] [-X proxy_version]
 [-x proxy_address[:port]] [hostname] [port[s]]
Command Summary:
-4 Use IPv4
                [...]
                -u UDP mode
                [...]

NetCat nos da la opción de usarlo en modo UDP (-u), tanto cuando lo empleamos en modo cliente como cuando lo empleamos en modo escucha. Esto nos permite una gran flexibilidad a la hora de definir conexiones. A modo de ejemplo, vamos a ver como podríamos establecer una conexión SSH a una máquina interna haciendo que el relay se estableciera mediante conexiones UDP al puerto 53:


En primer lugar, deberíamos poner en nuestro equipo "algo" a escuchar en el puerto 53/udp para recoger la conexión que nos vamos a mandar desde el equipo comprometido, y a su vez que este nos ofrezca el servicio SSH en algún puerto al que podamos conectar mediante un cliente SSH estándar. Para ello emplearemos NCat, que es la implementación que viene con la suite NMap del antiguo NetCat y que ya vimos EN ESTE POST. Como podéis ver, ponemos dos NCat's a la escucha, uno en el puerto 22/tcp y otro en el puerto 53/udp, conectados entre si. El orden en el que se llaman es importante, ya que el primero que se ejecuta debería ser el que primero vaya a recibir la conexión, en este caso el UDP.


A continuación, en la máquina comprometida, empleamos NetCat para hacer lo mismo que antes pero, esta vez, en modo cliente en lugar de a la escucha ¿Por qué usamos NetCat en lugar de NCat? Sencillamente porque NetCat está pensado para funcionar de forma standalone, mientras que NCat tiene algunas dependencias de las que podríamos no disponer en el sistema comprometido.

En este momento ya tenemos un NetCat que conecta al puerto 22/tcp de la máquina comprometida, que le pasa la información a otro NetCat que conecta a nuestro sistema al puerto 53/tcp y le pasa esta misma información al NCat que tenemos aquí a la escucha, que a su vez se lo pasa todo al NCat que hemos puesto a la escucha en nuestro puerto 22/tcp, por lo que... ¿Qué ocurrirá ahora si conectamos a nuestro puerto 22/tcp? Veamoslo:


Como podemos ver, conseguimos conectar al puerto SSH de la máquina comprometida, al que al principio no podríamos llegar, pero nos aprovechamos que la salida a través del 53/udp está permitida para cambiar de protocolo la conexión de tcp a udp, para luego en nuestro equipo deshacer este cambio y poder emplear un cliente estándar.

Es solo un pequeño ejemplo más de las cosas que se pueden hacer con NetCat/NCat. Por algo le llaman "la navaja suiza".

lunes, 10 de septiembre de 2012

Bypassing .NET Request Validation

Hace un par de semana leía ESTE artículo de Zamir Paltiel en el que comentaba haber descubierto una nueva forma de evadir la seguridad proporcionada por el Request Validation de .NET para realizar ataques de Cross Site Scripting (XSS).

Como ya sabéis, las aplicaciones web desarrolladas en entornos .NET (típicamente ASP.NET) tienen una serie de medidas de seguridad que vienen aplicadas por el framework y por defecto, lo cual dificulta algunos tipos de ataques a pesar de que existan vulnerabilidades en el código.

Una de las protecciones que proporciona el framework es el Request Validation (ver documentación oficial AQUÍ o la publicada por owasp AQUÍ). Esta protección, que como comentamos viene activada por defecto, filtra determinados caracteres en las entradas de datos de los usuarios que podrían ser utilizados para realizar ataques de scripting. Veamos, sacado de la guía OWASP, que caracteres son esos:


La guía OWASP no mencionada nada de versiones posteriores de ASP.NET, como la 4.0, pero si buscamos un poco podemos encontrar AQUÍ como parece que no ha habido diferencias en cuanto a los caracteres filtrados, aunque sí se ha ampliado el "espectro" de entradas a las que se le aplica esta protección.

En resumidas cuentas, a pesar de que en el código fuente exista una vulnerabilidad de XSS, si el desarrollador o administrador no ha deshabilitado la protección de Request Validation vamos a tener que no vamos a poder explotarlo con ninguna cadena que contenta el símbolo de abrir tag seguido de cualquier letra, el símbolo de admiración o la barra del tag cerrado. Si lo hacemos, nos encontraremos con un bonito error como el siguiente:


¿Cómo podemos evadir esta protección? Pues... en general, podríamos hablar de que tenemos dos opciones. La primera es aprovecharnos de que no en todos los XSS es necesario abrir y cerrar tags, así que eso nos da una opción para explotarlo según donde se encuentre la vulnerabilidad dentro del código HTML. Esta no creo que la pudiéramos considerar como "saltarse la protección", sino más bien como darse la vuelta y buscar otra puerta por donde entrar.

La otra opción es encontrar una forma de abusar de la flexibilidad que tienen los lenguajes HTML y Javascript, y de la tolerancia a fallos que tienen los navegadores para encontrar alguna forma "extraña" de ejecutar el script que sea aceptada por los navegadores pero que no siga la forma típica. En general, al ser formas "enrevesadas", suele pasar que solamente funcionan en un tipo concreto de navegador, ya que están un poco "fuera del estandar".

En este caso, Zamir Paltiel ha encontrado una forma de evadir esta protección y explotar XSS's en navegadores Internet Explorer, de la siguiente forma:


El tag "tag", con el símbolo porcentaje delante, es interpretado como un tag HTML correcto por Internet Explorer, por lo que es posible emplear las técnicas habituales, como por ejemplo utilizar el parámetro "style" para introducir la ejecución de un Alert en Javascript:


Como siempre, quien dice alert dice robo de credenciales o cualquier otra cosa, siempre y cuando no empleemos alguno de los otros caracteres "prohibidos" que harán saltar las protecciones de Request Validation.

Para un Pentest, digamos que con esto hemos cumplido, hemos encontrado un fallo en la aplicación que podemos explotar a pesar de las protecciones del framework. En el mundo real, los navegadores (o módulos adicionales como NoScript) disponen de protecciones anti-XSS que pueden impedir esta ejecución, así que habría que encadenar este bypass que hemos comentado en este post con el bypass de estas protecciones anti-XSS. Si os interesa un ejemplo de como saltar protecciones anti-XSS, a mi me gustó mucho el Write-Up que escribió Pepelux al reto de Infiltrados de Informática64, cuya primera fase trataba 100% sobre este tema.