Attacking Web Applications with Ffuf

Overview

En este módulo aprendí cómo enumerar archivos y directorios de una aplicación web, técnicas para descubrir vhosts y subdominios, fuzzing para encontrar parámetros ocultos por GET y POST, así como también para descubrir valores válidos a partir de los parámetros encontrados.

Si bien existen unas cuantas herramientas para aplicar fuzzing, en este módulo se explica el uso de Ffuf ('Fuzz Faster U Fool'), que está programada en Go.


Directory Fuzzing

Lo primero que tenemos que hacer es desplegar el target, ya que vamos a estar utilizando el mismo en todas las secciones del módulo, a excepción de la última.

Debemos encontrar otro directorio, aparte de /blog. Para eso, le indicamos a ffuf un diccionario de rutas y la URL bajo la cual queremos aplicar fuzzing.

Además, en mi caso le voy a añadir la flag -ic porque la herramienta considera los comentarios del copyright del diccionario como parte del mismo, por lo que el output es medio confuso. Con esa flag, los comentarios del comienzo del diccionario no se consideran.

$ ffuf -w /opt/useful/SecLists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ -u http://94.237.53.58:33138/FUZZ -ic

El otro directorio existente es forum.


Page Fuzzing

Acá hay que repetir tal cual el procedimiento que nos enseñan en la sección. Primero fuzzeamos dentro del directorio /blog para encontrar qué extensiones existen usando un nombre de archivo común en casi todas las aplicaciones web: index.*

ffuf -w /opt/useful/SecLists/Discovery/Web-Content/web-extensions.txt:FUZZ -u http://94.237.53.58:33138/blog/indexFUZZ -ic

En este caso, hay dos extensiones: .php y .phps

Ahora probamos a descubrir nombres de archivo con esas extensiones en específico.

$ ffuf -w /opt/useful/SecLists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ -u http://94.237.53.58:33138/blog/FUZZ.php -ic

Encontramos un archivo /home.php.

Si visitamos la página en el navegador, podremos visualizar la flag: HTB{bru73_f0r_c0mm0n_*********}.


Recursive Fuzzing

Este ejercicio consiste en aplicar fuzzing de forma recursiva para descubrir más directorios/archivos.

$ ffuf -w /opt/useful/SecLists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ -u http://94.237.53.58:33138/FUZZ -recursion -recursion-depth 1 -e .php -v -ic

Después de esperar un ratito, vemos un archivo interesante dentro del directorio /forum.

La flag es HTB{fuzz1n6_***_****}.


DNS Records

En Page Fuzzing, había un mensaje en la página web que indicaba que el panel de admin se había movido a academy.htb. Sin embargo, si intentáramos acceder con ese dominio, no lo lograríamos. Esto ocurre porque el sistema no sabe a qué IP tiene que resolver academy.htb. Para indicárselo, tenemos que añadir una línea al archivo /etc/hosts con el siguiente comando.

$ sudo sh -c 'echo "94.237.53.58 academy.htb" >> /etc/hosts'

Ahora sí podemos acceder, aunque no nos resulta de mucha utilidad ya que es exactamente la misma página accesible desde la IP. No se está aplicando Virtual Hosting.

Con el dominio:

Con la IP:


Sub-domain Fuzzing

El objetivo es encontrar un subdominio de 'inlanefreight.com' para clientes. Lo podemos encontrar de la siguiente forma:

ffuf -w /opt/useful/SecLists/Discovery/DNS/subdomains-top1million-5000.txt:FUZZ -u https://FUZZ.inlanefreight.com/ -ic

El subdominio es customer.inlanefreight.com.


Filtering Results

Ahora, a diferencia del fuzzing anterior, lo vamos a lanzar en modo VHost. La diferencia radica en que un VHost puede o no estar en registros DNS públicos, mientras que un subdominio se encuentra sí o sí en estos registros DNS. Si no tenemos esto en cuenta, puede que solo vayamos a descubrir subdominios públicos, pero que nunca lleguemos a aquellos que no son públicos pero que sin embargo existen.

Lanzamos un VHost fuzzing scan sobre 'academy.htb'.

ffuf -w /opt/useful/SecLists/Discovery/DNS/subdomains-top1million-5000.txt:FUZZ -u http://academy.htb:33138 -H "Host: FUZZ.academy.htb" -fs 986 -ic

Hay dos subdominios; la respuesta correcta es test.academy.htb.

Corresponde añadir ambos subdominios al /etc/hosts.

$ sudo sh -c 'echo "94.237.53.58 test.academy.htb" >> /etc/hosts'
$ sudo sh -c 'echo "94.237.53.58 admin.academy.htb" >> /etc/hosts'

Parameter Fuzzing - GET

Fuzzeamos de forma recursiva sobre el subdominio admin.academy.htb para encontrar rutas y archivos.

$ ffuf -w /opt/useful/SecLists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ -u http://admin.academy.htb:33138/FUZZ -recursion -recursion-depth 1 -e .php -v -ic

Encontramos un archivo admin.php dentro de un directorio admin.

Si visitamos la página, veremos que no contamos con acceso a la flag. Esto puede deberse a que la página está esperando recibir un parámetro por GET (en la propia URL) como validación.

Por eso, fuzzeamos por parámetros para encontrar alguno que sea válido. Como todas las respuestas devuelven un tamaño de 798 menos la correcta, con -fs 798 las ocultamos.

ffuf -w /opt/useful/SecLists/Discovery/Web-Content/burp-parameter-names.txt:FUZZ -u http://admin.academy.htb:33138/admin/admin.php?FUZZ=key -fs 798 -ic

El parámetro es user.

Sin embargo, si intentamos tramitar una petición GET con este parámetro y cualquier valor, veremos que este método ya no está siendo utilizado.


Parameter Fuzzing - POST

Ya fuzzeamos por parámetros GET, ahora toca lo mismo para parámetros POST.

$ ffuf -w /opt/useful/SecLists/Discovery/Web-Content/burp-parameter-names.txt:FUZZ -u http://admin.academy.htb:33138/admin/admin.php -X POST -d 'FUZZ=key' -H 'Content-Type: application/x-www-form-urlencoded' -fs 798 -ic 

Encontramos un parámetro id.

Si tramitamos una petición por POST con la data del id igualado a cualquier valor, veremos en la respuesta el mensaje 'Invalid id!', por lo que nuestro objetivo próximo será encontrar un valor que sea válido.

$ curl -X POST http://admin.academy.htb:33138/admin/admin.php -d 'id=1' -H 'Content-Type: application/x-www-form-urlencoded'

Value Fuzzing

Creamos un diccionario de ids que van desde el 1 hasta el 1000.

$ for i in $(seq 1 1000); do echo $i >> ids.txt; done

Utilizando el diccionario que acabamos de crear, fuzzeamos el parámetro id para encontrar cuál es el válido.

$ ffuf -w ids.txt:FUZZ -u http://admin.academy.htb:33138/admin/admin.php -X POST -d 'id=FUZZ' -H 'Content-Type: application/x-www-form-urlencoded' -fs 798,768 -ic 

El id que devuelve un tamaño de respuesta distinto de 798 y 768 es 73.

Lanzamos una petición por POST pasando el parámetro id igualado a 73.

$ curl -X POST http://admin.academy.htb:33138/admin/admin.php -d 'id=73' -H 'Content-Type: application/x-www-form-urlencoded'

Y finalmente obtenemos la flag.


Skills Assessment - Web Fuzzing

Desplegamos un nuevo target para esta sección integradora.

La primera consigna consiste en lanzar un escaneo sobre 'academy.htb' para descubrir subdominios. Sin embargo, no nos tenemos que olvidar de primero añadir el dominio al /etc/hosts.

$ sudo sh -c 'echo "83.136.252.214 academy.htb" >> /etc/hosts'

Ahora sí lanzamos el fuzzing:

$ ffuf -w /opt/useful/SecLists/Discovery/DNS/subdomains-top1million-5000.txt:FUZZ -u http://83.136.252.214:34951/ -H 'Host: FUZZ.academy.htb' -fs 985 -ic

Descubrimos tres subdominios: archive,test,faculty.

Continuamos con el siguiente ejercicio: descubrir qué extensiones son aceptadas para TODOS los subdominios. Primero, añadimos los subdominios que enumeramos al /etc/hosts.

$ sudo sh -c 'echo "83.136.252.214 test.academy.htb" >> /etc/hosts'
$ sudo sh -c 'echo "83.136.252.214 archive.academy.htb" >> /etc/hosts'
$ sudo sh -c 'echo "83.136.252.214 faculty.academy.htb" >> /etc/hosts'

Fuzzing para test.academy.htb:

Fuzzing para archive.academy.htb:

Fuzzing para faculty.academy.htb:

Las extensiones aceptadas son: .php,.phps,.php7

Siguiente task. Una de las páginas que vamos a identificar debería decir: 'You don't have access!'

Hay que averiguar cuál es la URL completa.

Para poder descubrirla, la idea es aplicar un fuzzing recursivo.

$ ffuf -w /opt/useful/SecLists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ -u http://faculty.academy.htb:34951/FUZZ -recursion -recursion-depth 1 -e .php -v -t 80 -ic

Con el parámetro -t le añadí hilos para lanzar múltiples tareas en paralelo y agilizar el proceso de fuerza bruta. De entre todos los resultados, este es el que nos interesa:

El formato de la respuesta es: http://faculty.academy.htb:PORT/courses/linux-security.php7

En esta misma página deberíamos poder encontrar múltiples parámetros.

Con este comando buscamos parámetros por POST:

$ ffuf -w /opt/useful/SecLists/Discovery/Web-Content/burp-parameter-names.txt:FUZZ -u http://faculty.academy.htb:34951/courses/linux-security.php7 -X POST -d 'FUZZ=key' -H 'Content-Type: application/x-www-form-urlencoded' -fs 774 -ic

Encontramos dos válidos: user,username.

Por último, fuzzeamos los parámetros con un diccionario que contemple nombres de usuario para encontrar un valor que retorne una flag.

Probamos con el parámetro user, pero no vamos a descubrir nada.

$ ffuf -w /opt/useful/SecLists/Usernames/xato-net-10-million-usernames.txt:FUZZ -u http://faculty.academy.htb:34951/courses/linux-security.php7 -X POST -d 'user=FUZZ' -H 'Content-Type: application/x-www-form-urlencoded' -fs 780 -t 100 -ic

Así que probamos con username:

ffuf -w /opt/useful/SecLists/Usernames/xato-net-10-million-usernames.txt:FUZZ -u http://faculty.academy.htb:34951/courses/linux-security.php7 -X POST -d 'username=FUZZ' -H 'Content-Type: application/x-www-form-urlencoded' -fs 781 -t 100 -ic

¡Encontramos un nombre de usuario válido para el parámetro!

Lanzamos una petición por POST tramitando como data el parámetro username con el valor harry y vemos la flag: HTB{w3b_fuzz1n6_******}.

curl -s -X POST http://faculty.academy.htb:34951/courses/linux-security.php7 -d 'username=harry'

Last updated