Fuzzing web: directorios, extensiones, subdominios y vhosts con ffuf, gobuster y feroxbuster

Descubrir rutas ocultas, copias de seguridad, vhosts y repositorios .git expuestos con ffuf y gobuster: qué diccionario usar y cómo filtrar falsos positivos.

· 3 min de lectura

La mitad de las entradas web del catálogo empiezan por algo que no está enlazado: un panel en /admin-old/, un config.php.bak, un subdominio dev. o una carpeta .git olvidada. Encontrarlo es pura fuerza bruta bien hecha. Esta guía cubre las tres variantes: directorios, vhosts y .git expuesto. La chuleta de enumeración web tiene todos los comandos.

Antes de lanzar nada

# Si nmap o el navegador te redirigen a un nombre, añádelo a /etc/hosts
echo '10.10.11.20 objetivo.htb' | sudo tee -a /etc/hosts

# Mira qué hay: tecnologías, cabeceras, robots.txt, sitemap.xml
whatweb http://objetivo.htb
curl -s http://objetivo.htb/robots.txt

La tecnología decide las extensiones: PHP (.php), ASP.NET (.aspx, .asp), Java (.jsp, .do, .action). Y siempre, .txt, .bak, .old, .zip.

1. Directorios y ficheros

# ffuf: rápido y con muchos filtros
ffuf -u http://objetivo.htb/FUZZ -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt -e .php,.txt,.bak -t 60

# feroxbuster: recursivo por defecto (entra en cada carpeta que encuentra)
feroxbuster -u http://objetivo.htb -w /usr/share/seclists/Discovery/Web-Content/raft-medium-words.txt -x php,txt

# gobuster
gobuster dir -u http://objetivo.htb -w /usr/share/seclists/Discovery/Web-Content/common.txt -x php,txt -t 50

Qué diccionario usar:

Diccionario (SecLists, Discovery/Web-Content/) Para qué
common.txt Una pasada rápida (unas 4.700 entradas)
raft-medium-directories.txt / raft-medium-words.txt La pasada normal
directory-list-2.3-medium.txt Cuando lo anterior no da nada (220.000 entradas)
api/api-endpoints.txt APIs
CMS/ Rutas de WordPress, Joomla, Drupal...

Filtrar los falsos positivos

Si todo devuelve 200 (o 302 al login), filtra por lo que tienen en común las respuestas falsas:

ffuf ... -fs 1532          # tamaño en bytes
ffuf ... -fw 12            # número de palabras
ffuf ... -fl 40            # número de líneas
ffuf ... -fr 'Not Found'   # una expresión en el cuerpo
ffuf ... -ac               # que ffuf calibre solo el filtro

Truco

Un 403 no es un callejón sin salida: significa que existe. Haz fuerza bruta dentro (/admin/FUZZ) o prueba a saltarte la restricción (/admin/., /%2e/admin, X-Original-URL: /admin).

2. Subdominios y virtual hosts

Un mismo servidor puede servir webs distintas según la cabecera Host. Si la web principal es objetivo.htb, busca dev.objetivo.htb, admin.objetivo.htb, api.objetivo.htb:

ffuf -u http://objetivo.htb -H 'Host: FUZZ.objetivo.htb' -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-20000.txt -ac
gobuster vhost -u http://objetivo.htb -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt --append-domain

Todo lo que no existe suele devolver lo mismo (la web principal o una redirección), así que el filtro de tamaño (-fs) o -ac es imprescindible. Cada vhost que encuentres va a /etc/hosts y se enumera desde cero.

Nota

El fuzzing de vhosts no es lo mismo que buscar subdominios en DNS. En HTB no hay DNS público: lo que funciona es cambiar la cabecera Host. Si el objetivo tiene un servidor DNS (puerto 53), prueba también una transferencia de zona: dig axfr objetivo.htb @10.10.11.20.

Ejemplos: en Devvortex y en LinkVortex, el subdominio dev. es la entrada; en Forge, admin.forge.htb solo responde desde dentro y hace falta una SSRF.

3. Repositorios .git expuestos

Si http://objetivo.htb/.git/HEAD devuelve algo como ref: refs/heads/master, puedes reconstruir todo el código fuente con su historial:

curl -s http://objetivo.htb/.git/HEAD
pipx install git-dumper
git-dumper http://objetivo.htb/.git/ codigo
cd codigo && git log --oneline && git show

Qué buscar: contraseñas que se borraron en un commit posterior (git log -p | grep -i pass), ficheros .env, claves de JWT o de sesión, y la lógica de la aplicación para encontrar el fallo sin tener que adivinarlo. Mira también el historial de git cuando el repositorio esté dentro de la máquina.

4. Otros ficheros que delatan

/.env  /.DS_Store  /.svn/entries  /.hg/  /backup.zip  /www.tar.gz
/web.config  /WEB-INF/web.xml  /server-status  /phpinfo.php  /.well-known/

Un .DS_Store lista los ficheros de una carpeta (python3 ds_store_exp.py); en Tomcat, /WEB-INF/web.xml y en Apache /server-status dan información interna si están accesibles.

Errores típicos

  • No sale nada con /FUZZ, pero sí en el navegador: te faltan las extensiones, o el servidor distingue /admin de /admin/. Prueba con -e y con barra final.
  • Los resultados cambian entre ejecuciones: vas demasiado rápido y el servidor limita o se cae. Baja los hilos (-t 20) o añade -rate 50.
  • Todos los vhosts devuelven 200: no has filtrado por tamaño. Mira el tamaño de una respuesta con un nombre inventado y usa -fs con ese valor.

Y después

Con el mapa completo, sigue la checklist web: versiones de cada componente (CVE públicos), formularios (inyección SQL, SSTI), subidas (subida de ficheros) y APIs (IDOR y mass assignment).

Practícalo en máquinas reales

Máquinas de Hack The Box donde se usa la técnica. Cada ▶ salta al minuto del vídeo de IppSec donde aparece.

Fuerza bruta de directorios 42 máquinas

Ver las 42 máquinas →

Fuzzing de vhosts y subdominios 47 máquinas

Ver las 47 máquinas →

Repositorio .git expuesto 10 máquinas

Ver las 10 máquinas →

¿Ves un error o echas algo en falta? Cuéntanoslo