Hoy vamos a resolver un Reto Web que publicamos hace ya bastante tiempo, por lo que primero quería disculparme por haber retrasado tanto la solución sobre todo ante el Team RTS (Abel, Malkov, Quartz) que fueron los únicos que consiguieron resolverlo y a los que les debo unas merecidas cervezas.
El reto es un sencillo ejercicio pensado para ser resuelto íntegramente con Burp (o ZAP) y seguir las entradas de Burp de mi compañero djurado. Aunque siempre podemos utilizar la herramienta con la que nos sintamos más cómodos.
Lo primero es configurar nuestro navegador para que use Brup como proxy y abrir http://challenge.fwr.es
La respuesta y el código de la web no nos dice mucho, así que vamos a buscar otras páginas accesibles.
En la cabecera vemos que el servidor es un Nginx, así que vamos a buscar archivos PHP (En el archivo robots.txt también teníamos una pista)
Cargamos la petición a Intruder y cargamos un diccionario, usamos SecLists/Discovery/Web_content/common.txt
La petición a debug.php nos devuelve OK (200) por lo que ya hemos encontrado el siguiente paso.
La página muestra un “Memory Dump” y muchos valores aleatorios junto a un botón para generar un nuevo reporte, pulsamos varias veces y vemos que genera nuevos “reportes”.
Al inspeccionar la petición en el Repaeter de Burp vemos que contiene muchos parámetros, uno por cada valor.
Si repetimos varias veces la petición la respuesta cambia, pero todo parece funcionar por lo que podemos descartar protecciones Anti-CSRF.
Jugamos alterando algunos de los valores y la aplicación responde con «Bad Checksum«. Al inspeccionar la página encontramos un código JavaScript con una función de Checksum, calculateChecksum() que se aplica en el envío del formulario.
Entendemos que estos campos tienen que cumplir la función para ser válidos, por lo que vamos a descartar modificar estos campos.
document.forms[0].elements[27] –> 1B
document.forms[0].elements[60] –> 3C
document.forms[0].elements[11] –> B
document.forms[0].elements[15] –> F
document.forms[0].elements[40] –> 28
document.forms[0].elements[98] –> 62
Ahora con Intruder intentamos modificar el valor de cada campo uno a uno y observamos que en las respuestas del servidor se encuentran algunos errores (500), dos de ellos con el mensaje Too much fuzzing y finaliza la carga de la página.
Parece que tenemos que descartar también modificar los campos 2A y 3E.
Sin embargo, el campo 51 devuelve un error y corta abruptamente la carga de la página, sin duda merece la pena investigarlo.
Preparamos un ataque con Intruder para fuzzear el campo 51, podemos probar varios de los diccionarios provistos en SecLists\Fuzzing o con los propios de Burp.
La mayoría de respuestas son de error (500), filtramos en el resultado estos para analizar detalladamente las respuestas 200 del servidor.
Interésate, parece que el campo es vulnerable a inyecciones SQL y rápidamente localizamos nuestra querida flag.
Abel del equipo RTS ha preparado un video de como solucionaron el reto.
Espero hayan disfrutado y nos sirva para recordar que cuando auditamos una aplicación web en caja negra no podemos olvidar fuzzear todos los parámetros, por muchos que sean, e ir filtrando y analizando todas las respuestas del servidor para encontrar posibles vectores de ataque.