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.

jueves, 30 de agosto de 2012

Explotando CVE-2012-4681 (Java 0-day)

Como ya sabréis, el pasado domingo se publicaba en el blog de FireEye la existencia de un exploit 0-day para Java que estaba siendo utilizado para infectar a los usuarios que navegaran por las webs controladas por los atacantes. Este tema ha sido ampliamente tratado en otros blogs durante estos días, tanto de habla Inglesa como Española (y entiendo que en todos los idiomas): SecurityByDefault, S21sec, Immunity, Hexale, Hispasec, Snort, AlienVault, etc (sin ningún orden concreto, tal y como los tengo en las pestañas del navegador).

En alguno de estos blogs mencionan la publicación del código fuente del exploit en Pastie.Org como si fuera el código fuente original, pero a mi me da la sensación de que es una PoC creada por jduck que posteriormente se ha convertido en un módulo para Metasploit.

Como ya conocéis todos mi debilidad por este framework, vamos a pegar un vistazo al módulo que han creado los chicos de Rapid7 para Metasploit, que podemos encontrar en "modules/exploits/multi/browser/java_jre17_exec.rb":


No sé si muchos de vosotros lo sabéis, pero no todos los exploits de Metasploit se encuentran 100% programados en Ruby. Algunos de ellos se encuentran programados aparte, y el módulo de Metasploit lo que hace es modificar el binario para añadir el Payload que elegimos desde el framework. Estos exploits programados aparte se encuentran en el directorio "data/exploits/". Concretamente, en éste módulo podemos ver como genera el payload que haya elegido el usuario, se codifica como un JAR y se "mezcla" con los ficheros existentes en "data/exploits/CVE-2012-XXXX/".

En este directorio tenemos un fichero "Exploit.class" que por supuesto podríamos decompilar y estudiar su contenido, pero es más inmediato ir al directorio donde Metasploit se guarda los códigos fuente de las partes que lleva compiladas (Meterpreter, elevación de privilegios o, como en este caso, Java): "external/source/".

En este directorio, dentro de "exploits/CVE-2012-XXXX/" podemos encontrar un fichero "Exploit.java" que es el código fuente del class del que hablamos antes. Si le pegamos un vistazo encontramos que realiza una única llamada a una función "disableSecurity()", que es la que lleva toda la chicha y otorga permisos de master del universo a la instancia, para luego ejecutar el payload que se haya elegido. En el código publicado por jduck era una calculadora y aquí lo han cambiado por un payload de Metasploit, pero el resto del código es identico.


Aquí entraríamos al análisis del propio exploit, que vamos a hacer muy por encima, ya que otros blogs se han ocupado de ello. Una de las cosas que vas a leer en otros blogs si decides profundizar más es que hablan mucho de que el exploit hace cosas "por reflexión". Si no eres un programador de Java o una persona que ya haya investigado con anterioridad sobre estos temas, es posible que no entiendas que quiere decir con "Reflexión": La manera habitual de utilizar un objeto es llamar a sus métodos, pero Java permite realizar ciertas acciones sobre ellos como listarlos, llamarlos e incluso cambiarlos, algo que no es posible en otros lenguajes y que recibe el nombre de "Reflexión".

En este caso vamos a optar por una explicación Top-Down. Vamos a suponer que existe una función mágica "SetField" que es capaz de cambiar el contenido de cualquier campo de cualquier objeto a nuestro gusto, y vamos a ver si entendemos que hace "disableSecurity()": No he encontrado documentación sobre el campo "acc", pero se comenta en la información publicada que es un método privado y que en principio no debería ser accesible más que desde el propio objeto, por lo que es posible que no se encuentre documentado. Esta función crea un objeto del tipo AccessControlContext con todos los permisos y se lo asigna a "acc". Al ejecutar ese Statement, el nuevo contexto es aplicado, con lo que a partir de este momento todo lo que se ejecuta lo hace sin ningún tipo de restricciones.

Pero... eso es confiado en la magia de "SetField" ¿cómo lo hará?


Aquí viene el primero de las vulnerabilidades utilizadas en este exploit. Siguiendo la linea de lo que hemos hecho antes, vamos a suponer que el método "GetClass" es un método que nos permite obtener de algún modo cualquiera de las clases que existan, independientemente de sus restricciones. Como podemos ver, se obtiene por reflexión el método "sun.awt.SunToolkit->getField()", que nos va a permitir acceder al campo que queramos del objeto que queramos, aunque sea privado (en este caso, por la llamada anterior, "acc"). Una vez que este campo es accesible, se puede cambiar su contenido con lo que la magia de esta función queda explicada.

Según he podido leer, este es el punto que hace que la vulnerabilidad funcione en jre7 pero no en jre6, ya que parece ser que el método getField() no puede ser accedido con esta técnica en jr6.

Pero claro, todo esto suponiendo que podemos acceder a "sun.awt.SunTookit", que como todos los objetos "sun.*" no debería ser accesible desde un Applet. Aquí viene la segunda de las vulnerabilidades. Vamos a ello:


En este caso, se usa una vulnerabilidad en "com.sun.beans.finder.ClassFinder.findClass" pero que se explota a través de una llamada a "forName" para poderse saltarse la restricción que comentábamos anteriormente y poder acceder al objeto "sun.awt.SunToolkit".

Si ahora todo esta magia, juntita y con un poco de Metasploit de por medio y tenemos...


Solo una cosa a tener en cuenta, en este caso no todos los Payloads habituales son compatibles con este exploit (por la forma en que ha sido programado). Si por ejemplo intentais utilizar el Meterpreter "tradicional" no os va a funcionar. Podeis mirar con el comando "show payloads" cuando estéis dentro del módulo cuales son los Payloads compatibles, que veréis que básicamente son un par de los genéricos y los de Java. En mi caso yo he usado el Meterpreter Java. Por supuesto, una vez obtenido el control del sistema, nada os impide subir el Meterpreter nativo.

Si quereis información en más en profundidad, sin desmerecer el gran trabajo que han hecho en otros blogs, a mi me ha gustado particularmente el de Immunity, por el gran detalle a bajo nivel y las referencias a la documentación oficial de Sun. Si por el contrario estás más preocupado de como protegerte, en SecurityByDefault han publicado las formas en las que podemos deshabilitar Java de los principales navegadores. Si trabajas en una empresa y no puedes permitirte deshabilitar Java porque usais aplicaciones internas que emplean applets Java, siempre tenéis la opción de bloquear las páginas con Applets Java en el perímetro, en los proxies o similar.