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.
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/adminde/admin/. Prueba con-ey 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
-fscon 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).