Hay un momento en casi todo pentest web en el que Nmap ya te ha dicho todo lo que sabe —puerto 80 abierto, Apache, título de la página— y el navegador no te enseña nada más que una landing genérica. Ahí es donde entra Gobuster.
La idea es simple: no todo lo que existe en un servidor web está enlazado desde la portada. Paneles de administración, backups olvidados, endpoints de API, entornos de desarrollo. Gobuster coge un diccionario, lanza miles de peticiones y te dice qué respuestas no son un 404.
Escrita en Go, su velocidad viene de las goroutines (hilos ligeros del propio lenguaje), que le permiten mantener decenas de peticiones en vuelo simultáneamente sin que la máquina se resienta. Es la razón por la que se ha comido buena parte del terreno que antes ocupaban DIRB o DirBuster.
Instalación y diccionarios
Gobuster viene preinstalado en Kali Linux y en la AttackBox de TryHackMe. Si no lo tienes:
sudo apt install gobusterComprueba que responde y de paso mira qué versión manejas —algunas flags han cambiado entre versiones:
gobuster versionWordlists
Gobuster sin diccionario no hace nada. La herramienta es rápida; la calidad del resultado depende del diccionario. En Kali los tienes en /usr/share/wordlists:
| Wordlist | Tamaño aprox. | Cuándo usarla |
|---|---|---|
dirb/common.txt | ~4.600 | Primer barrido rápido. Casi siempre suficiente en CTFs |
dirbuster/directory-list-2.3-small.txt | ~87.000 | Cuando common.txt no ha dado nada |
dirbuster/directory-list-2.3-medium.txt | ~220.000 | Barrido serio. Prepárate para esperar |
SecLists/Discovery/DNS/subdomains-top1million-5000.txt | 5.000 | Subdominios y vhosts |
Si SecLists no está instalado:
sudo apt install seclistsConsejo práctico: empieza siempre por
common.txt. Tirar lamediumde entrada contra una máquina de laboratorio es una forma excelente de perder veinte minutos para encontrar exactamente lo mismo.
Los modos de Gobuster
Gobuster no es un comando, son varios. El primer argumento siempre es el modo:
| Modo | Para qué sirve |
|---|---|
dir | Directorios y archivos ocultos en un servidor web |
dns | Subdominios, preguntando a un servidor DNS |
vhost | Virtual Hosts, manipulando la cabecera Host |
fuzz | Fuzzing genérico: sustituye la palabra FUZZ donde tú la pongas |
s3 | Buckets de AWS S3 accesibles públicamente |
La ayuda está bien escrita y es la referencia más fiable para tu versión concreta:
gobuster help # Ayuda general
gobuster dir --help # Todas las flags del modo dirModo dir: directorios y archivos
El modo estrella. Sintaxis mínima:
gobuster dir -u http://10.10.10.10 -w /usr/share/wordlists/dirb/common.txtFlags que vas a usar
| Flag | Función |
|---|---|
-u, --url | URL objetivo. Incluye el esquema (http:// o https://) |
-w, --wordlist | Ruta al diccionario |
-t, --threads | Hilos concurrentes (por defecto 10). -t 64 acelera muchísimo |
-x, --extensions | Extensiones a probar: -x php,txt,bak |
-k, --no-tls-validation | Ignora errores de certificado. Imprescindible en HTTPS de laboratorio |
-s, --status-codes | Whitelist de códigos considerados válidos |
-b, --status-codes-blacklist | Blacklist. Por defecto 404 |
-o, --output | Guarda el resultado en un archivo |
-r, --follow-redirect | Sigue los 301/302 en lugar de solo reportarlos |
La flag -x cambia el juego
Sin -x, Gobuster solo prueba las palabras tal cual: /admin, /config, /backup. Con -x prueba además cada palabra con cada extensión:
gobuster dir -u http://10.10.10.10 -w /usr/share/wordlists/dirb/common.txt -x php,txt,html,bakEso convierte config en config, config.php, config.txt, config.html y config.bak. Multiplica el tiempo de escaneo por cinco, pero es exactamente así como aparecen los backup.bak y los config.php.old que resuelven la máquina.
Elige las extensiones según la tecnología que ya conoces. Si Nmap te dijo que hay un IIS detrás,
-x asp,aspxtiene sentido y-x phpes tiempo tirado.
Escaneo completo típico
gobuster dir -u https://10.10.10.10 \
-w /usr/share/wordlists/dirb/common.txt \
-x php,txt,bak -t 64 -k -o gobuster_dir.txtCuando todo sale como "encontrado"
Un clásico: lanzas el escaneo y Gobuster te reporta cientos de rutas con código 200. No has encontrado un jackpot, has encontrado un servidor que responde 200 a todo (una SPA con catch-all, o una página de error mal configurada).
Dos formas de filtrar:
# Quedarte solo con códigos concretos
gobuster dir -u http://10.10.10.10 -w common.txt -s 200,301,302 -b ""
# Descartar respuestas por longitud (todas las falsas miden lo mismo)
gobuster dir -u http://10.10.10.10 -w common.txt --exclude-length 1234Ojo con
-s: Gobuster trae404en la blacklist por defecto y no acepta whitelist y blacklist a la vez. Si usas-s, vacía la otra con-b ""o te devolverá un error en lugar de resultados.
Modo dns: subdominios
Este modo no toca el servidor web. Pregunta a un servidor DNS si algo.dominio.com resuelve a alguna IP. Es la vía para descubrir dev.empresa.com, staging.empresa.com o mail.empresa.com.
gobuster dns -d tryhackme.com -w /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-5000.txt| Flag | Función |
|---|---|
-d, --domain | Dominio base sobre el que construir los subdominios |
-i, --show-ips | Muestra la IP de cada subdominio encontrado |
-c, --show-cname | Muestra el CNAME (útil para detectar subdomain takeover) |
-r, --resolver | Usa un DNS concreto: -r 8.8.8.8 |
La flag -r resuelve dos problemas distintos. Uno, tu resolver por defecto (el del router o el del ISP) puede empezar a limitarte peticiones a mitad de escaneo; apuntando a 8.8.8.8 o 1.1.1.1 desaparece. Dos, en un entorno interno con su propio DNS, es la única forma de ver los nombres que solo existen dentro de esa red.
gobuster dns -d empresa.local -w subdominios.txt -i -r 192.168.1.1Modo vhost: hosts virtuales
Aquí es donde mucha gente se atasca, así que vale la pena pararse.
Un mismo servidor con una sola IP puede alojar varios sitios web. Cuando tu navegador pide blog.empresa.com, resuelve el nombre por DNS, se conecta a la IP y envía la cabecera Host: blog.empresa.com. Nginx o Apache leen esa cabecera y deciden qué sitio servir. Eso es un Virtual Host.
La consecuencia interesante: puede existir un vhost que no tenga registro DNS público. Nadie puede llegar a él por nombre, pero si tú conoces la IP y mandas la cabecera correcta a mano, el servidor te lo entrega igualmente. Eso es exactamente lo que hace el modo vhost.
gobuster vhost -u http://10.10.10.10 -w /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-5000.txt --append-domainDNS vs VHost, en una frase cada uno
dnsle pregunta al servidor de nombres: "¿existesubdominio.dominio.com?"vhostle pregunta al servidor web: "dame el contenido desubdominio.dominio.com"
Por eso vhost encuentra cosas que dns nunca verá. En máquinas de CTF, donde no hay DNS público que valga, vhost es casi siempre el modo correcto.
--append-domain
En versiones recientes de Gobuster esta flag es obligatoria si tu diccionario contiene palabras sueltas (admin, dev, test) en lugar de subdominios completos. Sin ella, Gobuster envía Host: admin —que no significa nada para el servidor— en vez de Host: admin.empresa.thm.
Cuando el objetivo tiene un dominio asociado, apunta a él directamente y añádelo a /etc/hosts:
# 1. Registrar el dominio de la máquina
echo "10.10.10.10 empresa.thm" | sudo tee -a /etc/hosts
# 2. Buscar vhosts sobre ese dominio
gobuster vhost -u http://empresa.thm -w subdominios.txt --append-domainY cuando encuentres uno, recuerda añadirlo también a /etc/hosts antes de abrirlo en el navegador. Si no, tu equipo no sabrá a dónde ir.
El modo
vhostes propenso a falsos positivos: muchos servidores devuelven la página por defecto ante cualquierHostdesconocido, y Gobuster reporta todas. Fíjate en el tamaño de la respuesta que sale entre paréntesis: si trescientos resultados miden exactamente lo mismo, ese es el tamaño del ruido. Fíltralo con--exclude-length.
Modo fuzz: cuando el resto no encaja
Los tres modos anteriores cubren el 95% de los casos, pero a veces el parámetro que quieres probar no está en la ruta. El modo fuzz sustituye la palabra FUZZ allá donde la coloques —query string, cabecera, subdirectorio— y te deja fuzzear lo que quieras:
# Fuzzing de un parámetro GET
gobuster fuzz -u "http://10.10.10.10/index.php?FUZZ=test" -w parametros.txt --exclude-statuscodes 404En este modo no hay filtro por defecto, así que empieza siempre por descartar el código que devuelve el servidor cuando no encuentra nada.
Una nota sobre el ruido
Gobuster es rápido, y eso tiene un precio. Un escaneo con -t 64 y la wordlist medium son más de 200.000 peticiones contra un servidor en cuestión de minutos. En un CTF da igual. En un entorno real:
- Aparecerás en los logs del servidor. Todos y cada uno de los intentos.
- Puedes tumbar aplicaciones frágiles por saturación.
- Un WAF decente te bloqueará la IP antes de terminar.
Baja los hilos (-t 10 o menos) si el objetivo va lento o si te importa no hacer ruido. Y lo evidente: solo contra sistemas donde tengas autorización explícita.
Cheatsheet rápida
# Barrido inicial de directorios
gobuster dir -u http://10.10.10.10 -w /usr/share/wordlists/dirb/common.txt
# Con extensiones, hilos y guardando resultado
gobuster dir -u http://10.10.10.10 -w /usr/share/wordlists/dirb/common.txt \
-x php,txt,html,bak -t 64 -o gobuster.txt
# Objetivo HTTPS con certificado autofirmado
gobuster dir -u https://10.10.10.10 -w common.txt -k
# Filtrar por códigos de estado concretos
gobuster dir -u http://10.10.10.10 -w common.txt -s 200,301,302 -b ""
# Descartar falsos positivos por longitud de respuesta
gobuster dir -u http://10.10.10.10 -w common.txt --exclude-length 1234
# Subdominios vía DNS, mostrando IPs y con resolver propio
gobuster dns -d empresa.com -w subdominios-top5000.txt -i -r 8.8.8.8
# Virtual Hosts (el modo correcto en CTFs)
gobuster vhost -u http://empresa.thm -w subdominios-top5000.txt --append-domain
# Fuzzing genérico de un parámetro
gobuster fuzz -u "http://10.10.10.10/index.php?FUZZ=test" -w parametros.txt \
--exclude-statuscodes 404Gobuster no descubre vulnerabilidades: descubre superficie. El panel de login que no estaba enlazado, el dev.empresa.thm que nadie recordaba apagar, el backup.zip en la raíz. La vulnerabilidad viene después, y suele estar justo ahí.