Content Discovery
Web Content Enumeration
Stack fingerprinting
WhatWeb
whatweb fingerprints the HTTP stack: web server, framework, CMS, JS libs, analytics IDs, even JIRA versions. Run it first on any URL — it takes a second and often tells you exactly what to dig into next.
whatweb http://IP
wafw00f
Before any fuzzing, check whether a WAF sits in front of the target — it’ll shape which tool and rate you pick and explains weird 403s that would otherwise look like bugs in your scan.
wafw00f <domain>
Directory and file enumeration
Content discovery is the bulk of web enum. Three tools do the same job with different ergonomics — pick whichever one fits the target. gobuster for simple structured output, wfuzz for complex filters, ffuf for speed and flexibility.
gobuster — directories
Base directory brute with extension support. -b hides noisy status codes, -k skips TLS verification on self-signed certs.
gobuster dir -u <url> -w <wordlist.txt> -x <file_extensions>
gobuster dir -u <url> -w <wordlist.txt> -x <file_extensions> -b 403,404
HTTPS with cert issues:
gobuster dir -u <url> -w <wordlist.txt> -x <file_extensions> -b 403,404
gobuster dir -b 403,404 -u <url> --wordlist <wordlist.txt> -t 100 -k
API pattern brute-force — gobuster -p takes a patterns file where {GOBUSTER} expands to each word in the wordlist, good for versioned APIs. Example pattern file:
{GOBUSTER}/v1
{GOBUSTER}/v2
Run it:
gobuster dir -u <url> -w /usr/share/wordlists/dirb/big.txt -p pattern
wfuzz
wfuzz shines when the target has wonky response sizes and you need to filter by multiple criteria at once.
wfuzz -c --hc 404 -t 200 -w /usr/share/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt https://example.com/FUZZ
The filter flags:
--hs/ss "regex"— hide/show by regex in response--hc/sc CODE— hide/show by response code--hl/sl NUM— hide/show by number of lines--hw/sw NUM— hide/show by number of words--hh/sh NUM— hide/show by number of chars
ffuf
ffuf is the fastest and most flexible of the three. FUZZ is a placeholder you can place anywhere in the URL.
ffuf -w /opt/useful/seclists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ -u http://SERVER_IP:PORT/FUZZ
Filters mirror the wfuzz list:
--fr "regex"— hide/show by regex--fc/sc CODE— hide/show by code--fl/sl NUM— hide/show by lines--fw/sw NUM— hide/show by words--fs/sh NUM— hide/show by chars
Extension fuzzing — brute-force which extension a known page uses (e.g. index.php vs index.html):
ffuf -w /opt/useful/seclists/Discovery/Web-Content/web-extensions.txt:FUZZ -u http://SERVER_IP:PORT/blog/indexFUZZ
Page fuzzing — find pages under a known directory:
ffuf -w /opt/useful/seclists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ -u http://SERVER_IP:PORT/blog/FUZZ.php
Recursive scanning — let ffuf dive into directories it finds:
ffuf -w /opt/useful/seclists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ -u http://SERVER_IP:PORT/FUZZ -recursion -recursion-depth 1 -e .php -v
DNS subdomain enumeration
Subdomain brute uses DNS (not HTTP), so make sure the target is DNS-resolvable. --wildcard tells gobuster to ignore catch-all wildcards.
gobuster
gobuster dns -d <domain> -w <wordlist.txt> -i --wildcard
wfuzz
wfuzz -c --hc=400,404,404 -t 20 -w /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-
top1million-20000.txt -H "Host: FUZZ.example.com" -u http://example.com
ffuf
ffuf -w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-5000.txt:FUZZ -u https://FUZZ.inlanefreight.com/
VHost enumeration
VHost enum is different from DNS subdomain enum: you hit a single known IP and vary the Host: header to discover sites served from the same server. Useful when subdomains aren’t DNS-registered but are still served.
gobuster vhost -u <RHOST> -t 50 -w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-110000.txt
gobuster vhost -u <RHOST> -t 50 -w /usr/share/wordlists/seclists/Discovery/DNS/subdomains-top1million-110000.txt --append-domain
ffuf -w /opt/useful/seclists/Discovery/DNS/subdomains-top1million-5000.txt:FUZZ -u http://academy.htb:PORT/ -H 'Host: FUZZ.academy.htb'
Request / parameter fuzzing
When you know a specific endpoint exists, fuzzing the parameter name or value tells you what the app expects. ffuf -request replays a raw request file (from Burp), which is the cleanest way to fuzz complex multi-header requests like SSRF or SQLi-suspect endpoints.
ffuf -request ssrf.req -request-proto http -w <(seq 1 65535) -debug-log /dev/stdout
ffuf -w /opt/useful/seclists/Discovery/Web-Content/burp-parameter-names.txt:FUZZ -u http://admin.academy.htb:PORT/admin/admin.php?FUZZ=key -fs xxx
ffuf -w /opt/useful/seclists/Discovery/Web-Content/burp-parameter-names.txt:FUZZ -u http://admin.academy.htb:PORT/admin/admin.php -X POST -d 'FUZZ=key' -H 'Content-Type: application/x-www-form-urlencoded' -fs xxx
Nikto
nikto is the classic “quick vuln scan” — slow, noisy, and prone to false positives, but occasionally spots misconfigs the fuzzers miss (CGI, backup files, default creds). -Tuning b restricts to “software identification” — fingerprint-only, no active checks.
nikto -h inlanefreight.com -Tuning b
CMS-specific enumeration
WordPress — wpscan
The reference WordPress scanner. API token (free to register) unlocks the full vulnerability DB; without it you still get the basic user/theme/plugin enum.
Automatic scan:
wpscan --url http://example.com --api-token "token"
User enumeration:
wpscan --url https://example.com --enumerate u
Brute-force against discovered user:
wpscan --url example.com -U user -P /usr/share/wordlists/rockyou.txt
Additional variants — themes/plugins/users together, aggressive plugin detection, TLS-bypass for broken certs:
wpscan --url https://<RHOST> --enumerate u,t,p
wpscan --url https://<RHOST> --plugins-detection aggressive
wpscan --url https://<RHOST> --disable-tls-checks
wpscan --url https://<RHOST> --disable-tls-checks --enumerate u,t,p
wpscan --url http://<RHOST> -U <USERNAME> -P passwords.txt -t 50
WordPress — manual tricks
Version identification without wpscan — check the <meta> generator tag, readme.html / license.txt, HTTP response headers, or the REST API at /wp-json/v2/user. Quick greps:
curl -s <url> | grep WordPress
Enumerate plugins:
curl -s <url> | grep plugins
Enumerate themes:
curl -s <url> | grep themes
REST API user enum:
curl https://xxx/wp-json/wp/v2/users
Dictionaries:
/usr/share/wordlists/SecLists/Discovery/Contenido Web/CMS/wordpress.fuzz.txt/usr/share/wordlists/SecLists/Discovery/Web-Content/CMS/wp-themes.fuzz.txt
Login / auth paths to check:
/wp-login.php(often renamed tologin.php)/wp-admin/login.php/wp-admin/wp-login.phpxmlrpc.php
Important directories:
/wp-content— plugins and themes/wp-content/uploads/— uploaded fileswp-config.php— DB credentials
Joomla — droopescan
droopescan is the multi-CMS scanner — covers Joomla, Drupal, SilverStripe, and more.
droopescan scan joomla --url http://joomla-site.local/
Versions 4.0.0 to 4.2.7 are vulnerable to unauthenticated information disclosure (CVE-2023-23752), which dumps credentials and other data.
- Users:
http://<host>/api/v1/users?public=true - Config File:
http://<host>/api/index.php/v1/config/application?public=true
Drupal — droopescan
droopescan scan drupal --url https://example.com
Exposed .git / source
When the target’s .git directory leaks, GitTools pulls it down and reconstructs the working tree. Old commits frequently contain credentials, comments, and removed files worth looting.
./gitdumper.sh http://<RHOST>/.git/ /PATH/TO/FOLDER
./extractor.sh /PATH/TO/FOLDER/ /PATH/TO/FOLDER/
Walk the repo afterwards — especially git log for credential commits and git show for specific commits.
git log
git show <hash>
Building target-specific wordlists — cewl
cewl crawls a site and returns every word it finds. The resulting wordlist is gold for password spraying and for targeted brute-forcing of forms and logins on the same target.
# -m -> Minimum word length. Only words with at least 5 character
cewl http://url -m 5 -w wordlist.txt
Crawlers — ReconSpider
ReconSpider is a Scrapy-based crawler that enumerates URLs/endpoints for a given domain. Setup then run:
pip3 install scrapy
wget -O ReconSpider.zip https://academy.hackthebox.com/storage/modules/144/ReconSpider.v1.2.zip
unzip ReconSpider.zip
python3 ReconSpider.py http://inlanefreight.com