Skip to content

Wfuzz - Framework de Fuzzing Web

Wfuzz es un framework de fuzzing web modular y altamente configurable, diseñado para facilitar el proceso de pruebas de aplicaciones web mediante la inyección de payloads en cualquier campo de una solicitud HTTP. Su arquitectura basada en plugins y su flexibilidad lo convierten en una herramienta esencial para pentesters y investigadores de seguridad.

  • Inyección en cualquier punto de solicitud HTTP
  • Múltiples tipos de payload configurables
  • Combinación de payloads para pruebas complejas
  • Procesamiento de respuestas inteligente
  • Sistema de plugins extensible
  • Iteradores personalizados para payloads
  • Procesadores de respuesta configurables
  • Filtros avanzados por múltiples criterios
  • Filtrado por códigos de estado HTTP
  • Análisis por longitud de respuesta
  • Detección de patrones en contenido
  • Exportación de resultados en múltiples formatos
  • Todos los métodos HTTP
  • Autenticación múltiple (Basic, NTLM, Digest)
  • Soporte para proxies y cookies
  • Manejo de redirects configurable
Terminal window
# Instalación básica
pip install wfuzz
# Con dependencias adicionales para plugins
pip install wfuzz[complete]
# Verificar instalación
wfuzz --version
Terminal window
# Ejecutar con Docker
docker run -it --rm -v $(pwd):/work ghcr.io/xmendez/wfuzz wfuzz
# Con wordlists locales
docker run -it --rm -v $(pwd):/work -v /usr/share/wordlists:/wordlists ghcr.io/xmendez/wfuzz wfuzz
Terminal window
git clone https://github.com/xmendez/wfuzz.git
cd wfuzz
pip install -r requirements.txt
python setup.py install
Terminal window
# Debian/Ubuntu
sudo apt install wfuzz
# Arch Linux
sudo pacman -S wfuzz
# Kali Linux (preinstalado)
wfuzz --version
Terminal window
wfuzz [opciones] -w wordlist URL/FUZZ

La palabra FUZZ es el corazón de Wfuzz y marca el punto donde se inyectarán los payloads:

Terminal window
# Fuzzing de directorios
wfuzz -w wordlist.txt http://example.com/FUZZ
# Fuzzing de parámetros
wfuzz -w wordlist.txt http://example.com/page.php?param=FUZZ
# Fuzzing de headers
wfuzz -w wordlist.txt -H "X-Header: FUZZ" http://example.com
Terminal window
# Usar FUZ2Z, FUZ3Z, etc. para múltiples payloads
wfuzz -w users.txt -w passes.txt http://example.com/login?user=FUZZ&pass=FUZ2Z
Terminal window
-w, --wordlist FILE Wordlist para fuzzing
-z, --zE TYPE,PAR Payload inline (sin archivo)
--zD TYPE,PAR Payload con parámetros específicos
--zP TYPE,PAR,encoder Payload con encoder
Terminal window
--hc CODE Ocultar respuestas con código específico
--hl NUM Ocultar respuestas con X líneas
--hw NUM Ocultar respuestas con X palabras
--hh NUM Ocultar respuestas con X caracteres
--sc CODE Mostrar solo respuestas con código específico
--sl NUM Mostrar solo respuestas con X líneas
--sw NUM Mostrar solo respuestas con X palabras
--sh NUM Mostrar solo respuestas con X caracteres
--ss REGEX Mostrar solo si coincide regex
--hs REGEX Ocultar si coincide regex
Terminal window
-p PROXY Proxy HTTP (ej: 127.0.0.1:8080)
-t THREADS Número de threads (por defecto: 10)
-s DELAY Delay entre solicitudes (segundos)
--conn-delay DELAY Delay de conexión
--req-delay DELAY Delay entre solicitudes
-R DEPTH Profundidad de recursión
Terminal window
--basic USER:PASS Autenticación básica
--digest USER:PASS Autenticación digest
--ntlm USER:PASS Autenticación NTLM
-b COOKIE Cookies HTTP
-H HEADER Headers HTTP personalizados
Terminal window
# Wordlist básica
wfuzz -w /usr/share/wordlists/dirb/common.txt http://example.com/FUZZ
# Múltiples wordlists
wfuzz -w users.txt -w passwords.txt http://example.com/login?u=FUZZ&p=FUZ2Z
Terminal window
# Números del 1 al 100
wfuzz -z range,1-100 http://example.com/user/FUZZ
# Con padding (001, 002, etc.)
wfuzz -z range,1-100 --zP range,1-100,"%03d" http://example.com/user/FUZZ
Terminal window
# Lista de valores específicos
wfuzz -z list,admin-root-guest-test http://example.com/FUZZ
# Combinando con separador personalizado
wfuzz -z list,"admin|root|guest|test" --zD list,"|" http://example.com/FUZZ
Terminal window
# Entrada desde stdin
echo -e "admin\nroot\nguest" | wfuzz -z stdin http://example.com/FUZZ
# Combinando con otros comandos
cat userlist.txt | wfuzz -z stdin http://example.com/users/FUZZ
Terminal window
# Búsqueda básica de directorios
wfuzz -w /usr/share/wordlists/dirb/common.txt http://example.com/FUZZ
# Filtrar códigos 404
wfuzz -w /usr/share/wordlists/dirb/common.txt --hc 404 http://example.com/FUZZ
# Mostrar solo códigos 200
wfuzz -w /usr/share/wordlists/dirb/common.txt --sc 200 http://example.com/FUZZ
Terminal window
# Buscar archivos con extensiones específicas
wfuzz -w /usr/share/seclists/Discovery/Web-Content/common.txt -z list,php-html-txt-js http://example.com/FUZZ.FUZ2Z
# Archivos de backup
wfuzz -w /usr/share/wordlists/dirb/common.txt -z list,bak-backup-old-orig-tmp http://example.com/FUZZ.FUZ2Z
Terminal window
# Parámetros simples
wfuzz -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt http://example.com/page.php?FUZZ=test
# Valores de parámetros
wfuzz -w /usr/share/seclists/Fuzzing/special-chars.txt http://example.com/page.php?id=FUZZ
# Múltiples parámetros
wfuzz -w params.txt -w values.txt http://example.com/page.php?FUZZ=FUZ2Z
Terminal window
# Datos POST básicos
wfuzz -w usernames.txt -d "username=FUZZ&password=admin" http://example.com/login
# JSON POST
wfuzz -w payloads.txt -H "Content-Type: application/json" -d '{"user":"FUZZ","pass":"test"}' http://example.com/api/login
# XML POST
wfuzz -w payloads.txt -H "Content-Type: application/xml" -d '<user>FUZZ</user>' http://example.com/api
Terminal window
# Headers personalizados
wfuzz -w header-values.txt -H "X-Custom-Header: FUZZ" http://example.com
# User-Agent fuzzing
wfuzz -w user-agents.txt -H "User-Agent: FUZZ" http://example.com
# Authorization fuzzing
wfuzz -w tokens.txt -H "Authorization: Bearer FUZZ" http://example.com/api/data
Terminal window
# Valores de cookies
wfuzz -w session-ids.txt -b "sessionid=FUZZ" http://example.com/admin
# Múltiples cookies
wfuzz -w values.txt -b "auth=FUZZ;role=admin" http://example.com/panel
Terminal window
# Virtual host enumeration
wfuzz -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -H "Host: FUZZ.example.com" http://example.com
# Con filtrado por longitud
wfuzz -w subdomains.txt -H "Host: FUZZ.example.com" --hh 1234 http://example.com
Terminal window
# Ocultar códigos específicos
wfuzz -w wordlist.txt --hc 404,403 http://example.com/FUZZ
# Mostrar solo códigos exitosos
wfuzz -w wordlist.txt --sc 200,201,202 http://example.com/FUZZ
# Múltiples códigos
wfuzz -w wordlist.txt --hc 404 --hc 403 --hc 500 http://example.com/FUZZ
Terminal window
# Ocultar respuestas con longitud específica
wfuzz -w wordlist.txt --hh 1234 http://example.com/FUZZ
# Ocultar múltiples longitudes
wfuzz -w wordlist.txt --hh 1234,5678 http://example.com/FUZZ
# Mostrar solo longitudes específicas
wfuzz -w wordlist.txt --sh 5000-10000 http://example.com/FUZZ
Terminal window
# Ocultar respuestas que contengan texto específico
wfuzz -w wordlist.txt --hs "Not Found" http://example.com/FUZZ
# Mostrar solo respuestas que contengan texto
wfuzz -w wordlist.txt --ss "Welcome" http://example.com/FUZZ
# Filtrar por regex
wfuzz -w wordlist.txt --hs "error|exception|warning" http://example.com/FUZZ
Terminal window
# Múltiples criterios de filtrado
wfuzz -w wordlist.txt \
--hc 404,403 \
--hh 1234 \
--hs "Not Found" \
http://example.com/FUZZ

Script Bash para Enumeración Web Completa

Section titled “Script Bash para Enumeración Web Completa”
#!/bin/bash
TARGET="$1"
WORDLIST_DIR="/usr/share/seclists"
if [ -z "$TARGET" ]; then
echo "Uso: $0 <URL_objetivo>"
exit 1
fi
echo "[+] Iniciando fuzzing completo de $TARGET"
mkdir -p "wfuzz_$(echo $TARGET | tr '/:' '_')"
cd "wfuzz_$(echo $TARGET | tr '/:' '_')"
# 1. Enumeración de directorios
echo "[+] Fuzzing de directorios..."
wfuzz -w "$WORDLIST_DIR/Discovery/Web-Content/directory-list-2.3-medium.txt" \
--hc 404 \
-f directories.txt \
"$TARGET/FUZZ"
# 2. Enumeración de archivos
echo "[+] Fuzzing de archivos..."
wfuzz -w "$WORDLIST_DIR/Discovery/Web-Content/common.txt" \
-z list,php-html-txt-js-asp-aspx-jsp \
--hc 404 \
-f files.txt \
"$TARGET/FUZZ.FUZ2Z"
# 3. Parámetros GET
echo "[+] Fuzzing de parámetros GET..."
wfuzz -w "$WORDLIST_DIR/Discovery/Web-Content/burp-parameter-names.txt" \
--hc 404 \
-f parameters.txt \
"$TARGET/?FUZZ=test"
# 4. Archivos de backup
echo "[+] Fuzzing de archivos de backup..."
wfuzz -w "$WORDLIST_DIR/Discovery/Web-Content/common.txt" \
-z list,bak-backup-old-orig-tmp-save \
--hc 404 \
-f backups.txt \
"$TARGET/FUZZ.FUZ2Z"
echo "[+] Fuzzing completado. Revisar archivos de salida."
#!/usr/bin/env python3
import requests
import threading
import time
from queue import Queue
class CustomFuzzer:
def __init__(self, target, wordlist, threads=10):
self.target = target
self.wordlist = wordlist
self.threads = threads
self.queue = Queue()
self.results = []
self.session = requests.Session()
def load_wordlist(self):
"""Cargar wordlist en la cola"""
with open(self.wordlist, 'r') as f:
for line in f:
payload = line.strip()
if payload:
self.queue.put(payload)
def worker(self):
"""Worker thread para fuzzing"""
while not self.queue.empty():
payload = self.queue.get()
url = self.target.replace('FUZZ', payload)
try:
response = self.session.get(url, timeout=10)
result = {
'payload': payload,
'url': url,
'status': response.status_code,
'length': len(response.content),
'words': len(response.text.split())
}
# Filtrar respuestas interesantes
if response.status_code not in [404, 403]:
self.results.append(result)
print(f"[{response.status_code}] {url} ({len(response.content)} bytes)")
except Exception as e:
print(f"Error con {url}: {e}")
self.queue.task_done()
time.sleep(0.1) # Rate limiting
def run(self):
"""Ejecutar fuzzing"""
print(f"[+] Iniciando fuzzing de {self.target}")
print(f"[+] Threads: {self.threads}")
self.load_wordlist()
# Crear y iniciar threads
for _ in range(self.threads):
t = threading.Thread(target=self.worker)
t.daemon = True
t.start()
# Esperar completion
self.queue.join()
# Mostrar resultados
print(f"\n[+] Fuzzing completado. {len(self.results)} resultados:")
for result in self.results:
print(f" {result['status']} - {result['url']} ({result['length']} bytes)")
if __name__ == "__main__":
import sys
if len(sys.argv) != 3:
print("Uso: python3 fuzzer.py <URL con FUZZ> <wordlist>")
sys.exit(1)
fuzzer = CustomFuzzer(sys.argv[1], sys.argv[2])
fuzzer.run()

1. Búsqueda de Paneles de Administración

Section titled “1. Búsqueda de Paneles de Administración”
Terminal window
# Directorios administrativos
wfuzz -w /usr/share/seclists/Discovery/Web-Content/admin-panels.txt \
--hc 404 \
http://example.com/FUZZ
# Archivos de administración
wfuzz -w /usr/share/seclists/Discovery/Web-Content/admin-panels.txt \
-z list,php-asp-aspx-jsp \
--hc 404 \
http://example.com/FUZZ.FUZ2Z
Terminal window
# Endpoints de API
wfuzz -w /usr/share/seclists/Discovery/Web-Content/api/api-endpoints.txt \
--hc 404 \
http://api.example.com/v1/FUZZ
# Versiones de API
wfuzz -z range,1-10 \
--hc 404 \
http://api.example.com/vFUZZ/users
# IDs de recursos
wfuzz -z range,1-1000 \
--hc 404,403 \
http://api.example.com/v1/users/FUZZ
# Métodos HTTP en API
wfuzz -w endpoints.txt \
-X FUZZ \
--hc 404,405 \
http://api.example.com/v1/data
Terminal window
# Bypass de autenticación
wfuzz -w /usr/share/seclists/Fuzzing/auth-bypass.txt \
-H "Authorization: FUZZ" \
--hc 401,403 \
http://example.com/admin
# Fuzzing de usuarios y contraseñas
wfuzz -w users.txt -w passwords.txt \
-d "username=FUZZ&password=FUZ2Z" \
--hc 200 \
--hs "Invalid" \
http://example.com/login
# Tokens JWT
wfuzz -w jwt-tokens.txt \
-H "Authorization: Bearer FUZZ" \
--sc 200 \
http://example.com/api/profile
Terminal window
# Archivos de configuración
wfuzz -w /usr/share/seclists/Discovery/Web-Content/web-all.txt \
-z list,config-conf-cfg-ini-xml-yaml-yml \
--hc 404 \
http://example.com/FUZZ.FUZ2Z
# Archivos de respaldo
wfuzz -w common-files.txt \
-z list,"~,.bak,.backup,.old,.orig,.tmp,.save" \
--hc 404 \
http://example.com/FUZZFUZ2Z
# Logs y archivos de depuración
wfuzz -w /usr/share/seclists/Discovery/Web-Content/common.txt \
-z list,log-debug-error-access-trace \
--hc 404 \
http://example.com/FUZZ.FUZ2Z
Terminal window
# Listar plugins disponibles
wfuzz -e payloads
# Usar plugin específico
wfuzz -z burpstate,burp.state http://example.com/FUZZ
# Plugin de diccionario
wfuzz -z dict,/usr/share/dict/words http://example.com/FUZZ
Terminal window
# Listar processors
wfuzz -e processors
# Usar grep processor
wfuzz -w wordlist.txt --script=grep -s "admin" http://example.com/FUZZ
# Cookie processor
wfuzz -w wordlist.txt --script=cookies http://example.com/FUZZ
Terminal window
# Listar encoders disponibles
wfuzz -e encoders
# URL encoding
wfuzz -w payloads.txt --zP list,payloads.txt,urlencode http://example.com/?q=FUZZ
# Base64 encoding
wfuzz -w payloads.txt --zP list,payloads.txt,base64 http://example.com/?data=FUZZ
# HTML encoding
wfuzz -w payloads.txt --zP list,payloads.txt,html http://example.com/?input=FUZZ
Terminal window
# Formato JSON
wfuzz -w wordlist.txt -f results.json,json http://example.com/FUZZ
# Formato CSV
wfuzz -w wordlist.txt -f results.csv,csv http://example.com/FUZZ
# Formato HTML
wfuzz -w wordlist.txt -f results.html,html http://example.com/FUZZ
# Formato simple
wfuzz -w wordlist.txt -f results.txt,raw http://example.com/FUZZ
#!/bin/bash
RESULTS_FILE="$1"
if [ ! -f "$RESULTS_FILE" ]; then
echo "Uso: $0 <archivo_de_resultados>"
exit 1
fi
echo "[+] Análisis de resultados de Wfuzz"
echo "===================================="
# Contar total de hallazgos
echo "Total de URLs encontradas: $(wc -l < "$RESULTS_FILE")"
# Agrupar por código de estado
echo -e "\nCódigos de estado:"
grep -oE '[0-9]{3}' "$RESULTS_FILE" | sort | uniq -c | sort -nr
# Encontrar archivos interesantes por extensión
echo -e "\nArchivos por extensión:"
grep -oE '\.[a-z0-9]{2,4}' "$RESULTS_FILE" | sort | uniq -c | sort -nr
# URLs con parámetros
echo -e "\nURLs con parámetros:"
grep '?' "$RESULTS_FILE" | head -10
# Respuestas grandes (potencialmente interesantes)
echo -e "\nRespuestas más grandes:"
sort -k3 -nr "$RESULTS_FILE" | head -10
Terminal window
# Usar Burp como proxy
wfuzz -w wordlist.txt -p 127.0.0.1:8080 http://example.com/FUZZ
# Importar estado de Burp
wfuzz -z burpstate,burp_state.xml http://example.com/FUZZ
Terminal window
# Encontrar parámetros vulnerables a SQLi
wfuzz -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt \
--hc 404 \
http://example.com/page.php?FUZZ=1
# Luego usar SQLMap en parámetros encontrados
sqlmap -u "http://example.com/page.php?id=1" --batch
Terminal window
# Generar lista de URLs para Nuclei
wfuzz -w wordlist.txt --hc 404 -f urls.txt,raw http://example.com/FUZZ
# Procesar con Nuclei
nuclei -l urls.txt -t /path/to/templates/
Terminal window
# Para objetivos rápidos
wfuzz -w wordlist.txt -t 50 http://example.com/FUZZ
# Para objetivos con rate limiting
wfuzz -w wordlist.txt -t 5 -s 1 http://example.com/FUZZ
# Con delay personalizado
wfuzz -w wordlist.txt --req-delay 0.5 http://example.com/FUZZ
Terminal window
# Para wordlists grandes, usar chunks
split -l 1000 huge-wordlist.txt chunk_
for chunk in chunk_*; do
wfuzz -w "$chunk" --hc 404 http://example.com/FUZZ
done
Terminal window
# Reducir threads y agregar delay
wfuzz -w wordlist.txt -t 1 -s 2 http://example.com/FUZZ
# Usar proxy rotativo
wfuzz -w wordlist.txt -p proxy1.com:8080,proxy2.com:8080 http://example.com/FUZZ
Terminal window
# Investigar respuesta típica
curl -I http://example.com/nonexistent12345
# Filtrar por longitud de respuesta típica
wfuzz -w wordlist.txt --hh 1234 http://example.com/FUZZ
Terminal window
# Ignorar errores SSL
wfuzz -w wordlist.txt --insecure http://example.com/FUZZ
  • ✅ Conocer la aplicación objetivo antes de fuzzear
  • ✅ Usar wordlists apropiadas para el contexto
  • ✅ Establecer baseline de respuestas normales
  • ✅ Configurar filtros adecuados desde el inicio
  • ✅ Comenzar con fuzzing conservador (pocos threads)
  • ✅ Incrementar agresividad gradualmente
  • ✅ Monitorear aplicación objetivo durante fuzzing
  • ✅ Documentar hallazgos interesantes inmediatamente
  • ✅ Revisar manualmente hallazgos prometedores
  • ✅ Correlacionar resultados entre diferentes técnicas
  • ✅ Validar vulnerabilidades potenciales
  • ✅ Priorizar por impacto de seguridad
  • ✅ Obtener autorización explícita antes de fuzzear
  • ✅ Respetar rate limits para evitar DoS
  • ✅ Documentar todas las pruebas realizadas
  • ✅ Reportar vulnerabilidades de forma responsable
Terminal window
# Introspection queries
wfuzz -w graphql-queries.txt \
-H "Content-Type: application/json" \
-d '{"query":"FUZZ"}' \
http://example.com/graphql
# Mutations fuzzing
wfuzz -w mutations.txt \
-H "Content-Type: application/json" \
-d '{"query":"mutation { FUZZ }"}' \
http://example.com/graphql
Terminal window
# Usar plugin de WebSockets (si disponible)
wfuzz --script websocket -w payloads.txt ws://example.com/socket
Terminal window
# Diferentes encodings para bypass
wfuzz -w sqli-payloads.txt \
--zP list,sqli-payloads.txt,urlencode \
-H "X-Forwarded-For: 127.0.0.1" \
http://example.com/page.php?id=FUZZ
# User-Agents para bypass
wfuzz -w payloads.txt \
-H "User-Agent: GoogleBot/2.1" \
http://example.com/admin/FUZZ

Wfuzz es una herramienta extremadamente versátil que permite realizar fuzzing web avanzado con un control granular sobre cada aspecto del proceso. Su flexibilidad y extensibilidad la convierten en una opción excelente para auditorías de seguridad complejas y personalizadas.