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.

martes, 14 de agosto de 2012

Crawling con Sitemap2Proxy

En nuestro trabajo diario, tanto para hacer un Pentest como para muchas otras disciplinas dentro del mundo de la seguridad, es común que tengamos que hacer Crawling automático de algún sitio web para poder tener accesible toda su estructura y contenido sin tener que ir link a link pinchando en todos los enlaces.

El Crawling (Wikipedia English | Wikipedia Español), al contrario de lo que pueda parecer, no es algo nada trivial de hacer. Hace años, cuando todos los websites estaban formados por HTML estáticos, un wget recursivo bastaba para hacernos con el contenido completo de un site, pero hace años que los Javascript, Ajax, Flash y un sin fin de tecnologías web, hacen que el hecho de "seguir los enlaces" no resulte nada trivial.

Una alternativa a hacer un crawling tradicional es utilizar los Sitemaps. Un Sitemap es una fichero XML en el que el desarrollador o administrador de un sitio web introduce una especie de inventario de todas las URL que existen en su site, para facilitar el crawling por parte de los buscadores como Google, Yahoo, etc. Estos ficheros, tienen una pinta como la siguiente:


Como podeis ver, el XML proporciona información muy útil para un buscador, como por ejemplo las URLs que existen y la fecha de última modificación de cada una de ellas. Sabiendo esto, el buscador puede decidir si tiene indexada el contenido más reciente de la URL o si por el contrario es necesario volver a crawlear esa URL para actualizar su información.

Pues bien, hace un par de días observé que Robin Wood, compañero en el Advisory Board del SANS Institute, y al que seguro conoceis si seguís listas de correo de seguridad en Inglés, había publicado una herramienta llamada Sitemap2Proxy, que podeis descargar de su página web AQUÍ.


$ ./sitemap2proxy.rb 
You must specify either a file or URL to process

sitemap2proxy 1.0 Robin Wood (robin@digininja.org) (www.digininja.org)

Usage: sitemap2proxy [OPTIONS]
--help, -h: show help
--file, -f : local file to parse
--url, -u : URL to the file
--proxy, -p : address of the proxy
--ua, -a : specify an alternative user agent - default is Googlebot
-v: verbose

La herramienta está desarrollada en Ruby y puede funcionar de dos formas diferentes: Por un lado, puedes pasarle la URL donde está el fichero sitemap.xml y él se encarga de descargarlo y extraer las URLs. Por otro lado, puedes descargar tu mismo el fichero sitemap.xml (o .xml.gz, a veces viene comprimido) y hacer lo mismo desde un fichero local. El segundo parámetro obligatorio es el proxy (que generalmente será http://localhost:8080), que define a través de que proxy se va a acceder a las URLs que se encuentren al analizar el sitemap, con lo que vamos a poder tener un inventario de todas las URLs en nuestro proxy favorito (Burp, ZAP, o el que sea). Por último, opcionalmente podemos definir el User-Agent que se utilizará para acceder a las URLs, aunque por defecto usa el de GoogleBot, que debería ser suficiente como para no tener problemas. Al final, una llamada a esta herramienta podría ser tal que así:

$ ./sitemap2proxy.rb --url http://www.una-web.es/sitemap.xml --proxy http://localhost:8080 -v

Sabiendo esto, me decidí a probar que tal funcionaba la herramienta con alguna página conocida, así que realicé una sencilla búsqueda en Google para obtener algunos ficheros XML con los que poder jugar:


He tapado (y voy a tapar en el resto de capturas) los nombres de las webs, aunque por supuesto podeis obtenerlas de una forma trivial, pero al menos no os las doy directamente.

Cogiendo alguno de estos ficheros XML hice algunas pruebas, y en aquellos casos en que el fichero XML era único, la herramienta funcionaba a las mil maravillas, pero también me encontré con casos como este:


Como podéis ver, en algunos casos, los XML hacen referencia a su vez a otros XML de forma jerárquica, y la herramienta en este momento no está preparada para seguir recursivamente esta jerarquía, lo cual resulta un problema para hacer el crawling de la web.

Esto puede ser solucionado aplicando un poco de simple shellscript, es decir, haciendo que todos estos ficheros se descarguen a local y luego haciendo que la herramienta se ejecuta sobre cada uno de ellos. La otra opción, que fue la que hice yo, es hacer algunas modificaciones sobre la herramienta original para que sea capaz de seguir la jerarquía de XMLs y obtener así todas las URLs de la web.


Mientras estaba realizando estas pruebas pensé en publicar el código con mis modificaciones, pero tratándose de la herramienta de un compañero del Advisory Board me pareció muy poco elegante hacerlo, así que lo que he hecho ha sido ponerme en contacto con Robin y mandarle las modificaciones que he hecho, así que es probable que dentro de poco tengamos una versión 1.1 de la herramienta que incorpore esta capacidad de recursividad.

Por último, una pregunta que me surgió al acabar de probar la herramienta es ¿y si la web que queremos crawlear no tiene sitemap? Esta parte no la he llegado a probar, pero parece ser que existen herramientas on-line como ésta para generar el sitemap.xml de la web que le pasemos. Estas herramientas on-line no dejarán de hacer un crawling de la web, con toda la problemática que ello conlleva, pero de una forma mucho más anónima para nosotros :)