🛡️ Methodology Checklist

  • VHost fuzzing: ffuf -u http://[TARGET_IP] -H "Host: FUZZ.[DOMAIN]" -w [WORDLIST] -fs [DEFAULT_SIZE]
  • Subdomain fuzzing: ffuf -u http://FUZZ.[DOMAIN] -w [WORDLIST]
  • GET parameter fuzzing: ffuf -u http://[TARGET]/page?FUZZ=value -w [WORDLIST]
  • POST parameter fuzzing: ffuf -u http://[TARGET]/page -X POST -d "FUZZ=value" -H "Content-Type: application/x-www-form-urlencoded" -w [WORDLIST]
  • Value fuzzing: ffuf -u http://[TARGET]/page?id=FUZZ -w ids.txt
  • Filter responses: use -fc, -fs, -fw, -fl to reduce noise

🎯 Operational Context

Use when: Discovering hidden vhosts via Host header fuzzing or unknown GET/POST parameters via parameter fuzzing. Think Dumber First: ffuf -u http://[TARGET_IP]/ -H 'Host: FUZZ.target.htb' -w subdomains.txt -fs [default_size] for vhost. For params: ffuf -u http://[TARGET]/page.php?FUZZ=value -w parameters.txt -mc 200. Both take minutes and find what manual browsing misses. Skip when: Known complete list of vhosts and parameters from source code review — skip brute force.


⚡ Tactical Cheatsheet

CommandTactical Outcome
ffuf -w subdomains-top1million-5000.txt:FUZZ -u https://FUZZ.[DOMAIN]/Public subdomain DNS fuzzing
ffuf -w subdomains-top1million-5000.txt:FUZZ -u http://[TARGET_IP]:[PORT]/ -H 'Host: FUZZ.[DOMAIN]'VHost fuzzing — inject into Host header
ffuf -w subdomains-top1million-5000.txt:FUZZ -u http://[TARGET_IP]:[PORT]/ -H 'Host: FUZZ.[DOMAIN]' -fs [BASELINE_SIZE]VHost fuzz with false-positive filter
sudo sh -c 'echo "[TARGET_IP] admin.[DOMAIN]" >> /etc/hosts'Add discovered VHost to local routing
ffuf -w burp-parameter-names.txt:FUZZ -u http://[TARGET_IP]:[PORT]/admin.php?FUZZ=key -fs [BASELINE_SIZE]GET parameter name discovery
ffuf -w burp-parameter-names.txt:FUZZ -u http://[TARGET_IP]:[PORT]/admin.php -X POST -d 'FUZZ=key' -H 'Content-Type: application/x-www-form-urlencoded' -fs [BASELINE_SIZE]POST parameter name discovery
curl http://[TARGET_IP]:[PORT]/admin.php -X POST -d 'id=key' -H 'Content-Type: application/x-www-form-urlencoded'Verify discovered POST parameter with curl
for i in $(seq 1 1000); do echo $i >> ids.txt; doneGenerate sequential numeric wordlist for value fuzzing
ffuf -w ids.txt:FUZZ -u http://[TARGET_IP]:[PORT]/admin.php -X POST -d 'id=FUZZ' -H 'Content-Type: application/x-www-form-urlencoded' -fs [BASELINE_SIZE]Value fuzz discovered parameter
-fc [CODE]Filter by HTTP status code (e.g., -fc 403)
-fs [SIZE]Filter by response size
-fw [COUNT]Filter by word count
-fl [LINES]Filter by line count

🔬 Deep Dive & Workflow

Subdomain vs VHost

MethodUses DNSUse Case
Subdomain fuzzing (FUZZ.domain.com)Yes — public DNSPublic sites on different IPs
VHost fuzzing (-H 'Host: FUZZ.domain')No — sends to known IPInternal/private sites on same IP

If errors count = total requests → DNS resolution failed → switch to VHost fuzzing.

VHost Fuzzing Workflow

# Step 1: Run without filter (every result = 200 OK from fallback page)
ffuf -w subdomains.txt:FUZZ \
     -u http://[TARGET_IP]:[PORT]/ \
     -H 'Host: FUZZ.[DOMAIN]'
 
# Step 2: Note the baseline Size (e.g., 900)
 
# Step 3: Re-run with filter
ffuf -w subdomains.txt:FUZZ \
     -u http://[TARGET_IP]:[PORT]/ \
     -H 'Host: FUZZ.[DOMAIN]' \
     -fs 900
 
# Step 4: Add found VHost to /etc/hosts
sudo sh -c 'echo "[TARGET_IP]  admin.[DOMAIN]" >> /etc/hosts'

Multiple sizes: -fs 900,322

Parameter Fuzzing

# GET
ffuf -w burp-parameter-names.txt:FUZZ \
     -u http://admin.[DOMAIN]:[PORT]/admin.php?FUZZ=key \
     -fs [BASELINE_SIZE]
 
# POST (requires Content-Type header for PHP backends)
ffuf -w burp-parameter-names.txt:FUZZ \
     -u http://admin.[DOMAIN]:[PORT]/admin.php \
     -X POST -d 'FUZZ=key' \
     -H 'Content-Type: application/x-www-form-urlencoded' \
     -fs [BASELINE_SIZE]

“This method is deprecated” response = param name is correct, try different value or POST.

Value Fuzzing

# Generate numeric IDs
for i in $(seq 1 1000); do echo $i >> ids.txt; done
 
# Fuzz values
ffuf -w ids.txt:FUZZ \
     -u http://[TARGET_IP]:[PORT]/admin.php \
     -X POST -d 'id=FUZZ' \
     -H 'Content-Type: application/x-www-form-urlencoded' \
     -fs [BASELINE_SIZE]
 
# Confirm with curl
curl -X POST http://[TARGET_IP]:[PORT]/admin.php \
     -d 'id=[VALID_VALUE]' \
     -H 'Content-Type: application/x-www-form-urlencoded'

Filtering Reference

FlagFilters on
-fc 403HTTP status code
-fs 900Response byte size
-fw 423Word count
-fl 56Line count

🛠️ Troubleshooting & Edge Cases

ProblemCauseFix
Vhost fuzz returns all same sizeCatch-all vhostFilter by size: add -fs [default_response_size]; test baseline first with invalid vhost
Parameter fuzz returns too many 200sApplication returns 200 for all paramsFilter by response size or content: -fs [size] or -fr 'not found'
Vhost fuzzing misses internal namesWordlist lacks internal naming patternsAdd company-specific prefixes to wordlist: dev-, staging-, api-, admin-, int-
POST parameter fuzzing format wrongffuf body vs queryFor POST params: -X POST -d 'FUZZ=test' -H 'Content-Type: application/x-www-form-urlencoded'
Rate limiting blocks ffufTarget rate limits aggressive scanningAdd -rate 100 and -p 0.1 (100ms delay) to slow scan

📝 Reporting Trigger

Finding Title: Hidden Virtual Hosts and Parameters Discovered via Fuzzing Impact: Undiscovered virtual hosts and hidden HTTP parameters expose unprotected application endpoints, admin panels, and debug functionality not accessible through normal application flow. Root Cause: No comprehensive endpoint inventory. Internal virtual hosts rely on DNS obscurity rather than authentication controls. Recommendation: Document and inventory all virtual hosts and API parameters. Apply authentication and authorization to all discovered endpoints. Remove debug parameters from production. Implement API gateway with explicit parameter allowlisting.