¿Qué es FFUF?
FFUF (Fuzz Faster U Fool) es una herramienta de fuzzing web escrita en Go. Es la sucesora moderna de Gobuster y Dirb, con ventajas significativas.
¿Cuándo usar fuzzing en un pentest?
El fuzzing web es una de las fases más importantes en cualquier auditoría de seguridad de aplicaciones web. Se ejecuta típicamente después del reconocimiento pasivo (OSINT, DNS enumeration) y antes del explotamiento activo. Los escenarios principales donde FFUF es fundamental son:
- Enumeración de directorios y archivos — Descubrir rutas no enlazadas, paneles de administración, backups expuestos y archivos de configuración que el servidor no muestra en el navegado normal.
- Descubrimiento de parámetros — Encontrar parámetros ocultos en URLs y formularios que pueden ser vulnerables a SQLi, XSS o LFI.
- Virtual host enumeration — Detectar otros sitios alojados en el mismo servidor que responden a diferentes Host headers.
- Bypass de controles de acceso — Probar si existen rutas protegidas por autenticación débil o por obscuridad.
- Fuzzing de valores de parámetros — Enviar payloads para descubrir inyecciones, desbordamientos o errores reveladores.
En un pentest profesional, el fuzzing te permite mapear la superficie de ataque de un objetivo de forma sistemática y rápida. Sin él, estarías adivinando rutas y parámetros a ciegas. FFUF acelera este proceso drásticamente: una wordlist de 20.000 palabras se ejecuta en segundos, no minutos.
- Velocidad — Multithreaded en Go, mucho más rápido que Gobuster
- Filtros avanzados — Filtra por tamaño, palabras, líneas, regex, código HTTP
- Auto-calibrate — Detecta falsos positivos automáticamente
- Múltiples modos — Directory, parameter, vhost, POST data, header fuzzing
- Output flexible — JSON, CSV, HTML, Markdown
Importante: FFUF es una herramienta de auditoría de seguridad. Solo debe usarse con autorización explícita del propietario del sistema.
Instalación
# Kali Linux — preinstalado
ffuf -h
# Go install
go install github.com/ffuf/ffuf/v2@latest
# Docker
docker run -it ffuf/ffuf -h
# Archivo release
# https://github.com/ffuf/ffuf/releases
Directory Fuzzing
El uso más común: descubrir directorios y archivos ocultos en el servidor web.
# Fuzzing básico
ffuf -u https://target.com/FUZZ \
-w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
# El marcador FUZZ se reemplaza por cada palabra de la wordlist
Eliminar falsos positivos
El mayor problema del fuzzing es el ruido. FFUF lo resuelve con filtros:
# Auto-calibrate (recomendado para empezar)
ffuf -u https://target.com/FUZZ -w wordlist.txt -ac
# Filtrar por tamaño de respuesta
# Primero ejecutar sin filtro para ver el tamaño de la página 404
ffuf -u https://target.com/FUZZ -w wordlist.txt
# Si la página 404 tiene size=4440, excluir:
ffuf -u https://target.com/FUZZ -w wordlist.txt -fs 4440
# Filtrar por número de palabras
ffuf -u https://target.com/FUZZ -w wordlist.txt -fw 128
# Filtrar por líneas
ffuf -u https://target.com/FUZZ -w wordlist.txt -fl 42
# Combinar filtros
ffuf -u https://target.com/FUZZ -w wordlist.txt \
-mc 200,301,302,403 -fs 4440 -fw 128
Recursive fuzzing
# Fuzzing recursivo (descender en directorios encontrados)
ffuf -u https://target.com/FUZZ -w wordlist.txt \
-recursion -recursion-depth 2
# Con filtro de exclude
ffuf -u https://target.com/FUZZ -w wordlist.txt \
-recursion -fs 4440
Parameter Discovery
Descubrir parámetros ocultos en URLs y formularios:
# GET parameter fuzzing
ffuf -u "https://target.com/page?id=1&FUZZ=test" \
-w /usr/share/wordlists/seclists/Discovery/Web-Content/burp-parameter-names.txt \
-fc 400
# POST parameter fuzzing
ffuf -u https://target.com/api/login \
-X POST -d "FUZZ=admin" \
-H "Content-Type: application/x-www-form-urlencoded" \
-w params.txt -fc 400
# POST value fuzzing (probar valores contra parámetro conocido)
ffuf -u https://target.com/api/search \
-X POST -d "query=FUZZ" \
-w payloads.txt -H "Content-Type: application/json" \
-fs 0
Virtual Host Discovery
Encontrar virtual hosts ocultos en el mismo servidor:
# Vhost fuzzing
ffuf -u https://192.168.1.10/ \
-H "Host: FUZZ.target.com" \
-w subdomains.txt -fs 0
# Con auto-calibrate
ffuf -u https://192.168.1.10/ \
-H "Host: FUZZ.target.com" \
-w subdomains.txt -ac
Header Fuzzing
# Fuzzing de headers personalizados
ffuf -u https://target.com/admin \
-H "FUZZ: admin" \
-w /usr/share/wordlists/seclists/Discovery/Web-Content/burp-parameter-names.txt \
-fs 4440
# Fuzzing de cookies
ffuf -u https://target.com/admin \
-b "session=abc123; FUZZ=admin" \
-w params.txt -fs 4440
# Fuzzing de User-Agent
ffuf -u https://target.com/ \
-H "User-Agent: FUZZ" \
-w user-agents.txt -fs 4440
Caso práctico: Enumeration completa de un target web
Un flujo de trabajo real de pentest web con FFUF sigue estos pasos:
Paso 1: Fuzzing inicial de directorios
# Primera pasada con wordlist común
ffuf -u https://target.com/FUZZ -w /usr/share/wordlists/dirb/common.txt -ac -o step1.json -of json
Revisar los resultados y anotar directorios interesantes: /admin, /backup, /api, /config.
Paso 2: Fuzzing profundo con wordlist mayor
# Segunda pasada sobre directorios encontrados
ffuf -u https://target.com/admin/FUZZ \
-w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt \
-ac -o step2.json -of json
Aquí es donde suelen aparecer resultados más específicos del target.
Paso 3: Descubrimiento de parámetros
# Buscar parámetros en endpoints encontrados
ffuf -u "https://target.com/api/users?id=1&FUZZ=test" \
-w /usr/share/wordlists/seclists/Discovery/Web-Content/burp-parameter-names.txt \
-fc 400 -o step3.json -of json
Paso 4: Virtual host enumeration
# Enumerar virtual hosts
ffuf -u https://target.com/ \
-H "Host: FUZZ.target.com" \
-w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-5000.txt \
-fs 0 -o step4.json -of json
Paso 5: Fuzzing de valores
# Probar payloads contra parámetros descubiertos
ffuf -u "https://target.com/api/users?id=FUZZ" \
-w payloads.txt -mc 200,500 -o step5.json -of json
Tip: Usa el flag
-xpara configurar un proxy y capturar todo en Burp Suite durante el fuzzing. Ejemplo:-x http://127.0.0.1:8080
# JSON output
ffuf -u https://target.com/FUZZ -w wordlist.txt \
-o results.json -of json
# CSV output
ffuf -u https://target.com/FUZZ -w wordlist.txt \
-o results.csv -of csv
# HTML report
ffuf -u https://target.com/FUZZ -w wordlist.txt \
-o report.html -of html
# Todos los formatos disponibles
# json, ejson, html, md, csv, all
FFUF vs. Gobuster vs. Dirb
| Característica | FFUF | Gobuster | Dirb |
|---|---|---|---|
| Velocidad | Muy rápida (Go) | Rápida (Go) | Lenta (C) |
| Filtros | -fs, -fw, -fl, -ac | -s (solo status) | Limitados |
| Auto-calibrate | Sí | No | No |
| Modos | dir, vhost, param, POST | dir, dns, vhost | Solo dir |
| Output | JSON, CSV, HTML | Solo texto | Solo texto |
| Recursión | Sí | Sí | No |
| Ideal para | Pentest profesional | Uso rápido | Legacy |
Recomendación: Usa FFUF para todo fuzzing web. Gobuster solo paraDNS brute-force rápido (gobuster dns).
Tuning de rendimiento
Ajustar los parámetros de rendimiento es clave para evitar bloqueos y optimizar el tiempo de escaneo.
Threads (-t)
# Default: 40 threads. Subir para objetivos lentos sin rate limit
ffuf -u https://target.com/FUZZ -w wordlist.txt -t 100
# Bajar para objetivos sensibles o con WAF
ffuf -u https://target.com/FUZZ -w wordlist.txt -t 10
Delay entre peticiones (-p)
# Delay aleatorio entre 0.05 y 0.15 segundos
ffuf -u https://target.com/FUZZ -w wordlist.txt -p 0.05-0.15
# Delay fijo de 200ms (para WAF agresivos)
ffuf -u https://target.com/FUZZ -w wordlist.txt -p 0.2
Timeout y reintentos
# Timeout de 10 segundos por petición
ffuf -u https://target.com/FUZZ -w wordlist.txt -timeout 10
# Retry automático en errores de conexión
ffuf -u https://target.com/FUZZ -w wordlist.txt -timeout 5
Configuraciones recomendadas por escenario
| Escenario | Threads | Delay | Notas |
|---|---|---|---|
| Lab / local | 200-500 | 0 | Sin límites, máxima velocidad |
| Target remoto sin WAF | 50-100 | 0 | Buena velocidad sin saturar |
| Target con WAF básico | 10-20 | 0.05-0.1 | Evitar detección |
| Target con WAF agresivo | 5-10 | 0.1-0.3 | Mínimo footprint |
| Producción activa | 5 | 0.2+ | No afectar al servicio |
Tip: Monitorea los tiempos de respuesta. Si la latencia sube significativamente, reduce threads o añade delay. Un servidor sobrecargado también puede generar falsos negativos.
Wordlists recomendadas
# Directorios comunes
/usr/share/wordlists/dirb/common.txt
/usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
# SecLists (mejor opción)
https://github.com/danielmiessler/SecLists
SecLists/Discovery/Web-Content/common.txt
SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt
# Parámetros
SecLists/Discovery/Web-Content/burp-parameter-names.txt
# Subdominios
SecLists/Discovery/DNS/subdomains-top1million-5000.txt
Fuzzing con múltiples wordlists
En escenarios reales, una sola wordlist no es suficiente. FFUF permite combinar y encadenar múltiples wordlists para una enumeración más completa.
Combinar wordlists con -w
FFUF soporta múltiples wordlists en un solo scan usando el parámetro -w con dos marcadores de posición (FUZZ y FUZZ2):
# Fuzzing cruzado de directorios y extensiones
ffuf -u https://target.com/FUZZ/FUZZ2 \
-w wordlist1.txt:FUZZ -w extensions.txt:FUZZ2
# Extensiones comunes
echo -e ".php\n.txt\n.bak\n.zip\n.tar.gz\n.sql" > extensions.txt
Encadenar resultados entre scans
El flujo más efectivo es usar los resultados de un scan como entrada para el siguiente:
# 1. Directorio fuzzing — extraer rutas encontradas
ffuf -u https://target.com/FUZZ -w common.txt -ac \
| grep "Status: 200" | awk '{print $2}' > found_dirs.txt
# 2. Usar esas rutas como base para un segundo fuzzing
for dir in $(cat found_dirs.txt); do
ffuf -u "https://target.com/$dir/FUZZ" \
-w extended.txt -ac -fc 404
done
Merge manual de wordlists
# Combinar wordlists de diferentes fuentes
cat /usr/share/wordlists/dirb/common.txt \
/usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt \
SecLists/Discovery/Web-Content/raft-large-directories.txt \
| sort -u > merged_wordlist.txt
# Eliminar duplicados y ordenar
wc -l merged_wordlist.txt
Tip: El orden importa. Empieza con wordlists pequeñas (
common.txt~4.600 palabras) y ve escalando a wordlists más grandes (directory-list-2.3-medium.txt~220.000 palabras) solo si los resultados iniciales lo justifican.
FFUF en automación de pentesting
FFUF se integra perfectamente en flujos automatizados de pentesting. Su output en JSON facilita el parseo y la combinación con otras herramientas.
Script de enumeration automatizado
#!/bin/bash
TARGET=$1
OUTPUT_DIR="ffuf_$(date +%Y%m%d_%H%M%S)"
mkdir -p "$OUTPUT_DIR"
echo "[*] Fase 1: Directory fuzzing"
ffuf -u "https://$TARGET/FUZZ" \
-w /usr/share/wordlists/dirb/common.txt \
-ac -mc 200,301,302,403 \
-o "$OUTPUT_DIR/dirs.json" -of json -s
echo "[*] Fase 2: Parameter discovery"
ffuf -u "https://$TARGET/?FUZZ=test" \
-w /usr/share/wordlists/seclists/Discovery/Web-Content/burp-parameter-names.txt \
-fc 400 -o "$OUTPUT_DIR/params.json" -of json -s
echo "[*] Fase 3: Vhost enumeration"
ffuf -u "https://$TARGET/" \
-H "Host: FUZZ.$TARGET" \
-w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-5000.txt \
-fs 0 -o "$OUTPUT_DIR/vhosts.json" -of json -s
echo "[*] Resultados guardados en $OUTPUT_DIR/"
Chaining con otras herramientas
# FFUF + httpx: verificar hosts activos antes de fuzzing
ffuf -u https://target.com/FUZZ -w subdomains.txt -ac -of json -o vhosts.json -s
cat vhosts.json | jq -r '.results[].input.FUZZ' | httpx -silent | tee live_hosts.txt
# FFUF + nuclei: fuzzing y escaneo de vulnerabilidades en cadena
ffuf -u https://target.com/FUZZ -w common.txt -ac -of json -o dirs.json -s
cat dirs.json | jq -r '.results[] | select(.status==200) | .url' | nuclei -t cves/
# FFUF + Waybackurls: combinar wordlists generadas
waybackurls target.com | unfurl paths | sort -u > wayback_paths.txt
ffuf -u https://target.com/FUZZ -w wayback_paths.txt -ac -fs 4440
Output JSON para procesamiento
# Extraer solo URLs con status 200 del output JSON
cat results.json | jq -r '.results[] | select(.status==200) | .url'
# Generar reporte rápido
cat results.json | jq -r '.results[] | "\(.status) \(.length) \(.url)"' | sort -u > report.txt
Tip: El flag
-s(silent) reduce el output a lo esencial, ideal para scripts donde necesitas parsear solo los hallazgos.
Errores Comunes
Demasiados resultados falsos
El problema más frecuente. Si la página 404 personalizada del servidor devuelve un status 200, cada palabra de la wordlist parecerá un hallazgo válido. Solución:
# Auto-calibrate (detecta falsos positivos automáticamente)
ffuf -u https://target.com/FUZZ -w wordlist.txt -ac
# Excluir por tamaño de la página 404
ffuf -u https://target.com/FUZZ -w wordlist.txt -fs 4440
# Excluir por número de palabras
ffuf -u https://target.com/FUZZ -w wordlist.txt -fw 128
# Excluir por líneas
ffuf -u https://target.com/FUZZ -w wordlist.txt -fl 42
Si -ac no funciona bien, ejecuta FFUF una vez sin filtros, identifica el tamaño de la respuesta 404, y usa -fs con ese valor.
Rate limiting / 429 Too Many Requests
Muchos servidores aplican rate limiting después de demasiadas peticiones. Solución:
# Delay de 100ms entre peticiones
ffuf -u https://target.com/FUZZ -w wordlist.txt -p 0.1
# Reducir threads (default es 40)
ffuf -u https://target.com/FUZZ -w wordlist.txt -t 10
# Combinar delay y threads bajos
ffuf -u https://target.com/FUZZ -w wordlist.txt -p 0.05 -t 5
Si el servidor bloquea por IP, considera rotar proxies con -x http://proxy:port.
"FUZZ not found in wordlist"
El marcador debe ser exactamente FUZZ en mayúsculas. FFUF no acepta fuzz, Fuzz o FUZZZ. Si necesitas dos marcadores, usa FUZZ y FUZZ2.
Resultados vacíos (0 hallazgos)
Causas posibles:
- La URL no es accesible desde tu máquina. Verifica con
curl -I https://target.com/ - La wordlist está vacía o corrupta. Comprueba con
wc -l wordlist.txt - Estás filtrando demasiado. Prueba sin flags
-fs,-fw,-fl - El sitio responde todo con 302/redirección. Prueba añadiendo
-mc 302para ver si redirige a login
Conexión rechazada / timeout
# Verificar conectividad básica
curl -I https://target.com/
# Aumentar timeout
ffuf -u https://target.com/FUZZ -w wordlist.txt -timeout 10
# Si hay problemas SSL
ffuf -u https://target.com/FUZZ -w wordlist.txt -x http://127.0.0.1:8080
Encoder issues con caracteres especiales
Si tu wordlist contiene caracteres especiales o acentos, asegúrate de que el archivo esté en UTF-8:
file -i wordlist.txt
# Si no es UTF-8:
iconv -f ISO-8859-1 -t UTF-8 wordlist.txt > wordlist_utf8.txt
Práctica en Laboratorios
# DVWA — Directory fuzzing
ffuf -u http://localhost/dvwa/FUZZ -w common.txt -fc 401
# Juice Shop — Parameter fuzzing
ffuf -u "http://localhost:3000/api/Products/1?FUZZ=test" \
-w burp-parameter-names.txt -fc 400
# HackTheBox — máquinas con web fuzzing
# Probar en: Jerry, Arctic, Blue, Optimum