martes, septiembre 08, 2009

Reto Hacking X: Solucionario (II de III)

*****************************************************************************************
- Reto Hacking X: Solucionario (I de III)
- Reto Hacking X: Solucionario (II de III)
- Reto Hacking X: Solucionario (III de III)
*****************************************************************************************

Román resolvió esta parte de forma diferente ya que él no disponía de herramienta de “Blind XPath Injection” propia ni estaba por la labor de crear una. Lo que hizo fue partir de la única herramienta pública existente: BXPI.

Su funcionalidad es actualmente muy limitada y de hecho no te permite parametrizar la inyección ni inyectar en una cabecera HTTP cualquiera ni emplear cookies… por lo cual era inútil para el reto… ¿o no? Al menos servía para realizar el proceso de inyección en el caso más básico (un parámetro GET y asumiendo que la consulta XPath es también simple) y en definitiva, con todas las condiciones favorables. La original idea de Román fue encadenar la salida de esta herramienta a un Proxy tipo MITM como “WebScarab” y utilizar las capacidades de scripting en Java de este Proxy (“Bean Shell”) para adaptar la inyección básica que implementa BXPI al escenario real del reto (que era totalmente diferente al escenario básico que cubre BXPI).

Veámoslo en detalle:

Parametrización de la inyección.

BXPI inyectará una cadena como la siguiente:

en' or '0'='1

Que deberemos transformar, antes de pasarla a la aplicación web vulnerable, en esta otra cadena:

en') and ('0'='1' or 'a'='

Si os fijáis bien, la transformación deberá consistir en extraer la condición de arriba (en rojo), a la que le falta una comilla de cierre (añadida en verde en la cadena de abajo) y finalmente insertarla en una construcción compatible con el proceso de booleanización que ya explicamos anteriormente.

Lugar de la inyección.

BXPI no permite inyectar en una cabecera HTTP cualquiera. De hecho, sólo soporta utilizar un parámetro GET. Las peticiones que enviará BXPI serán del tipo:

GET http://retohackingx.elladodelmal.com:80/privado/rhx_level2_homer.aspx?&lang=xxx& HTTP/1.1

Observamos que BXPI envía incorrectamente separadores de parámetros (“&”) que realmente no son necesarios. Pero en cualquier caso no nos importa: basta con extraer de la petición la cadena de inyección (en rojo). El nombre del parámetro usado tampoco importa y nos lo inventamos nosotros mismos a la hora de configurar BXPI.

El código Java que se ha diseñado extrae la cadena a partir del primer “=” y que acabe en “&” (que se corresponde exactamente con la cadena marcada en rojo). También se encargará de insertar la cadena convenientemente tratada y modificada en la cabecera “Accept-Language”, es decir, aquella vulnerable a inyección XPath.

Codificaciones especiales.

Tal y como vimos anteriormente, el guión (“-”) y la coma (“,”) necesitan ser “escapados”. Para ello los reemplazamos en la cadena a inyectar por “%2D” y “%2C”, respectivamente.

Manejo de cookies.

BXPI no soporta cookies. Necesitaríamos implementar esta funcionalidad en nuestro script. El problema es que el script no tiene estado sino que es una simple función de transformación que reescribe una petición web realizando siempre los mismos cambios y no tiene una variable de estado que se pueda leer/escribir para pasar datos entre peticiones. Se nos ocurren varias soluciones: una podría ser abrir desde Java un fichero donde se lea/escriba la cookie de sesión, y que antes de lanzar el proceso de inyección habría sido convenientemente inicializado con una cookie válida. Finalmente caemos en la cuenta de que WebScarab ya contempla esta necesidad de manejo de cookies y bastará con marcar un “check-box” en la configuración para tener el problema resuelto.

El script que implementa todo lo explicado más arriba es el siguiente:


Script en WebScarab

Y la opción de WebScarab que permite delegar el manejo de cookies a la propia herramienta se encuentra en:


Delegación del manejo de cookies en WebScarab

El proceso completo, una vez configurado WebScarab adecuadamente, pasaría por navegar a la página del reto vulnerable con Internet Explorer con el Proxy configurado (para que WebScarab guarde la cookie de sesión) y posteriormente arrancar BXPI (que tomará la configuración de Proxy del Internet Explorer), teclear la URL (http://retohackingx.elladodelmal.com:80/privado/rhx_level2_homer.aspx), pinchar en “Cargar Página” y añadir un parámetro “lang” que se marcará como inyectable. Finalmente arrancamos el proceso de inyección ciega y tras unas horas obtendremos el mismo XML que obtuvo la herramienta de Dani:


Fichero XML obtenido

Volviendo al XML, todo hacía pensar que la URL del último comentario era la que nos llevaría a la solución de la fase, pero nada más lejos de la realidad, porque en realidad nos redirige a un vídeo de YouTube que nada tenía que ver con el reto (Rick Astley - Never Gonna Give You Up).

Puesto que en el contenido de los ficheros CSS tampoco encontramos ninguna información de utilidad, solamente nos queda seguir analizando ese directorio que por su nombre tan peculiar (“estilosestilosos”) parece que se nos haya querido ocultar e impedir su acceso fortuito sin haber resuelto esta fase.

Al acceder a la ruta de “estilosestilosos” usando un navegador web, observamos que el servidor nos lista todo el contenido del directorio. Llaman la atención dos fragmentos de ficheros de Word de 162 bytes, ambos idénticos, cuyos nombres eran “~$temp.doc” y “~$ticion_homer_simpson.doc”.

Tras examinar minuciosamente todo su contenido, únicamente podíamos leer las cadenas “Way.Smithers” y “Docu”, por más que intentemos extraer algún metadato adicional (usando la herramienta FOCA online o incluso su versión de escritorio no obteníamos nada).

[Continuará...]

Autores del Solucionario: Dani Kachakil & RoMaNSoFt

*****************************************************************************************
- Reto Hacking X: Solucionario (I de III)
- Reto Hacking X: Solucionario (II de III)
- Reto Hacking X: Solucionario (III de III)
*****************************************************************************************

17 comentarios:

  1. Juas, qué bueno, quien inyecta a un inyector, tiene mil inyecciones de perdón¿?

    ResponderEliminar
  2. Joer, yo me tuve que bajar el código fuente de BXPI y 'tocarlo' a mano, además de sortear el tema de sesiones (a los 20 minutos el servidor me invalidaba la sesión). Pero al final fue todo como la seda xD.

    Un saludo

    ResponderEliminar
  3. @tayoken: me niego a programar una tool con la presión de un reto!! Porque para hacerlo bien habría necesitado tener también una maqueta donde poder inyectar de forma controlada (viendo errores, etc). Vamos, un curro.

    @anonimo: no te creas, este truquillo del Webscarab que se me ocurrió me dio quebraderos de cabeza... Nunca había usado Java y aunque eran 3 líneas al más mínimo error te saltaba una excepción en el proxy con errores "no demasiado esclarecedores". Por otro lado, le estuve dando muchas vueltas al tema de la caducidad de sesión hasta que se me ocurrió mirar si Webscarab ya dispondría de alguna forma de hacerlo... et voilà. Y por último, Webscarab iba cada vez más lento y se quedaba tostado cuando llevabas un cierto número de peticiones (no recuerdo, del orden de 4000 :?). Al principio pensé que era fallo de BXPI pero parece ser que no, que era Webscarab y su puñetero Java. Lo solucioné reiniciando Webscarab de vez en cuando (sin parar el proceso BXPI, obviamente).

    Vamos, que me costó lo suyo...

    -r

    ResponderEliminar
  4. @romansoft:

    Sip, el webscarab (java en general) es muy lento. Yo por eso prefiero el Burp, aunque no dispone de la posibilidad de ponerle scripts "a pelo" :(.

    Por lo general, estos programas necesitan muucha memoria, lo recomendado es ejecutarlos teniendo en cuenta eso.

    java -jar -Xmx512m xxx.jar

    (Con esto, el Webscarab tendrá 512Mb de heap, por si te sirve para el próximo reto xD)

    Slds,

    ResponderEliminar
  5. Nada como una buena aplicación multihilo. Menos mal que la mía se bajó todo el fichero en unas 3 horas y eso que el tema de las sesiones (la cookie ASPXAUTH) lo arreglaba a mano cada vez que caducaba...

    Si llega a ser por el apaño de RoMaNSoFt, Chema pierde la apuesta de las 24h seguro, jeje ;-)

    ResponderEliminar
  6. jeje, me suena taaanto todo esto ;-).

    Cuando nos disteis la pista del idioma localizamos la inyección bastante rápido, pero como no teníamos ni idea de xpath (y menos de xpath injection) divagamos bastante antes de hacer algo "útil".

    Como RoMaNSoFt, empezamos intentando usar BXPI a través de WebScarab para enchufar la inyección en la cabecera, y de paso ver los logs para comprobar cómo era la secuencia de peticiones, a modo de manual.

    El caso es que como lo primero que hacía el BXPI era la comprobación, y no podíamos ver qué peticiones hacía después (una mirada rápida del código no me aclaraba nada), abandonamos esa línea. Empezábamos a intuir que BXPI estaba bastante limitado, y no vimos muy claro el modificar las inyecciones, ya que no sabíamos qué más problemas nos íbamos a encontrar.

    Para ir centrando un poco el tema, hicimos unas cuantas pruebas con perl, y al final Sheldon volvió al BXPI y apañó el código para hacer la inyección que queríamos e intercambiar los resultados verdadero y falso...

    Para solucionar lo de las cookies, lo lanzamos a través del WebScarab, que como comentáis nos mataba la máquina una y otra vez.

    Total, que al final utilizamos la peor solución posible: hubo que tocar código extraño y lo enchufamos a través del WebScarab con una degradación de rendimiento brutal.

    Nos costó muchísimo tiempo darnos cuenta del filtrado de caracteres, y de hecho repetimos muchas pruebas pensando que los errores venían de caducidad de la sesión :-((.

    Por suerte, en cuanto apareció la ruta de estilosestilosos nos costó menos acabar que sacar el siguiente carácter, porque si no todavía estaríamos cambiando de sistema para hacer la inyección :-/.

    De hecho, no llegamos a descargar el xml completo :-((.

    @RoMaNSoFt: ¿Eliminabas los parámetros que descubría él sólo de la query y sólo dejabas el de la inyección?

    Desde el desconocimiento total del mundo de los asp, aprovecho para preguntar ¿qué validaciones se realizan de los parámetros que llevan todos los formularios por defecto? ¿Alguna referencia que vaya directa al grano?

    @Kachakil: Totalmente de acuerdo en lo de la aplicación multihilo, pero me temo que no todos somos tan aplicados como tú ;-). Yo me puse de deberes para agosto sacar el xml completo, y aún no me he puesto... :-P

    ResponderEliminar
  7. @ramandi: sólo dejaba el parámetro que necesitaba, por simplicidad (habría dado igual añadir 20 parámetros más... en realidad, tal y como programé mi script sólo cogería el primero...).

    Respecto a lo del .asp que preguntas, no lo se; yo los retos siempre los saco deduciendo a base de prueba y error. Seguro que el maligno puede hablar más del tema...

    -r

    ResponderEliminar
  8. Juas juas, al final todos tiramos de WebScarab? xD (menos Dani está claro).
    En mi caso el filtrado lo vi intentando hacer la aplicación en Perl antes de tirar de BXPI, pero mi problema con las cookies me obligo a sacar 3 medios XML antes de obtener el final. Lo arreglé a lo guarro con un script en Python que se autentificaba, guardaba la cookie y la almacenaba en un fichero, WebScarab la leía del fichero y listo. Muy sucio así que no os imagináis mi cara al ver en el solucionario que WebScarab te lo hace solo... U_U"

    @Roman: Yo jugaba con la baza que me manejo en java, pero a cada 200 peticiones había que cambiar de sesión para que fuese "rápido" y aún así tarde en sacarlo: 27125 peticiones en 04:31:04.1878624 horas.

    Muy muy clarito el Solucionario, mola ver como lo han ido sacando otros :)

    ResponderEliminar
  9. Yo me curré un programilla en C#. Es rudimentario, y el código da pena (apesta en realidad), pero me sirvió para el reto. Lo que hice fue fusilar (cortar y pegar) métodos del BXPI, fundamentalmente toda la parte de tratamiento de nodos, etc. Apañé un poco de código propio, basado en una buena encapsulación del HttpWebRequest que encontré en Internet y a la que corregí un par de errores y amplié para que tratase correctamente las cabeceras html e hiciera la sustitución de caracteres rebeldes.

    Una vez depurado y lanzado, extrajo el xml de corrido en unas 2 horas 40 minutos. Tuve que cortar varios intentos preliminares, porque mostrar demasiada información en pantalla lo ralentizaba bastante, pero cuando decidí que funcionaba y que lo único que necesitaba era el resultado final, funcionó aceptablemente bien.

    Saludos

    ResponderEliminar
  10. Webscarab vs Burp.

    Los que preferís Webscarab habeis probado Burp. Parece que gana por mayoría.

    A mi que me gusta Burp me siento un poco como un bicho raro...

    ResponderEliminar
  11. Antes que nada, gracias a todos por compartir vuestros comentarios, ya que hay muchos detalles que enriquecen nuestras soluciones. Esperamos que nos contéis más cosas cuando se publique la tercera parte del solucionario, ¿ok?.

    De paso os cuento una breve anécdota, porque no sé si recordaréis que el reto estaba diseñado específicamente para que yo no lo ganara... ;-)

    El caso es que la herramienta de XPath la tenía desarrollada hace bastante tiempo y en su día se la pasé a Chema (justo antes del reto 5, porque intuí que podrían ir por ahí los tiros), pero resulta que se confundió y creyó que la que le pasé era otra que él tenía por ahí, la cual no extraía ni los comentarios ni las processing instructions del XML (que es precisamente donde residía la información interesante del reto, supuestamente para que se me escapara).

    Ese pequeño desliz es el que le dio la vuelta a la tortilla, prácticamente dándome más ventaja, pero aún así me costó bastante tiempo determinar que mi herramienta fallaba por culpa de la codificación del guión (y luego de la maldita coma), ya que pensé que Chema había detectado algún fallo en mi código en determinadas circunstancias, así que también me tocó examinar minuciosamente algunas partes del código fuente de BXPI para poder descartar totalmente esa posibilidad.

    ¡Saludos!

    ResponderEliminar
  12. @Ramandi: ASP.NET solamente lanza errores ante intentos de inyección de etiquetas (anti-XSS), es decir, si se inyectan cosas como <esta>.

    Aunque se puede desactivar a nivel de aplicación o de página concreta, por defecto está habilitada.

    Para más detalles, busca "ValidateRequest". Por cierto, esta característica está presente desde la primera versión de ASP.NET, no de ASP "clásico".

    ResponderEliminar
  13. Gracias Dani, no sabía nada de esa protección!!

    Yo me refería sobre todo a los campos ocultos __VIEWSTATE, __EVENTTARGET, __EVENTARGUMENT y __EVENTVALIDATION.

    He encontrado esta página que los explica bastante bien, y entiendo que alguno de los campos sirve para evitar CSRF y cosas así, que era lo que sospechaba.

    Por eso me extrañaba que pudieran eliminarse esos campos y que el sistema no respondiera con error, pero parece que hay que activar ese comportamiento para cada control llamando a RegisterEventForValidation (análisis totalmente simplista, lo sé :-/).

    Y yo venga a conservar campos en todos los sitios por si acaso... soy un paquete, pa la próxima le copio a RoMaNSoFt ;-).

    ResponderEliminar
  14. Total, que la página era:

    http://msdn.microsoft.com/es-es/magazine/cc163512.aspx

    ResponderEliminar
  15. @Ramandi: Vale, no había entendido que te referías a esos campos ocultos... La aplicación no fallaba al omitirlos porque en realidad no había ningún control o formulario que enviara un postback con datos, así que ASP.NET simplemente lo considera como una nueva petición y no desencadena ningún evento especial en la parte del servidor (como podría ser un click en un botón, la modificación de un textbox o combo, etc).

    Supongo que en este caso funcionaba igualmente porque el código que mostraba las diferentes camisetas seguramente estaba asociado al evento Load de la página, que se desencadena siempre.

    ResponderEliminar
  16. Lo dicho, soy un paquete. En este caso era una petición get directa, y aunque la página incluía la etiqueta form, no había posibilidad de enviar ningún formulario, así que mi pregunta no tiene sentido.

    Si hubiera sido un formulario de verdad entiendo que sí sería necesario devolver los parámetros recibidos.

    Muchas gracias!!

    El aprendizaje de parámetros del BXPI me confunde... :P

    ResponderEliminar
  17. alguien podria explicar como funciona el burp???... he oido que funciona muy bien.

    ResponderEliminar