ffuf
Fast web fuzzer for content discovery, parameter fuzzing, and vhost enumeration. Use only on authorized targets.
Quickstart
# Directory discovery
ffuf -u https://target.com/FUZZ -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt
# With extensions
ffuf -u https://target.com/FUZZ -w wordlist.txt -e .php,.txt,.bak
# Filter by size (hide 404 pages)
ffuf -u https://target.com/FUZZ -w wordlist.txt -fs 1234
# Virtual host discovery
ffuf -u http://10.10.10.10 -H "Host: FUZZ.target.com" -w subdomains.txt
# Parameter fuzzing
ffuf -u https://target.com/page?FUZZ=test -w params.txt
Core Concepts
| Concept |
Description |
| FUZZ keyword |
Marks injection point (URL, headers, body) |
| Matchers |
Show results matching criteria (status, size, words) |
| Filters |
Hide results matching criteria (noise reduction) |
| Autocalibrate |
-ac auto-filters baseline responses |
| Modes |
clusterbomb, pitchfork for multi-wordlist fuzzing |
Syntax
ffuf -u <url-with-FUZZ> -w <wordlist> [options]
ffuf -request <raw.txt> -w <wordlist> [options]
Options
Input & Target
| Option |
Description |
-u <url> |
Target URL with FUZZ keyword |
-w <file> |
Wordlist (can map: -w words.txt:W) |
-w <file>:KEYWORD |
Named wordlist for multi-position |
-mode <mode> |
clusterbomb, pitchfork, sniper |
-request <file> |
Use raw HTTP request file |
-request-proto https |
Protocol for raw request |
Request Options
| Option |
Description |
-H "Header: FUZZ" |
Add/fuzz header |
-X POST |
HTTP method |
-d "data=FUZZ" |
Request body |
-b "cookie=value" |
Cookies |
-r |
Follow redirects |
-x http://proxy:8080 |
Proxy (Burp/Caido) |
Matchers (show results)
| Option |
Description |
-mc 200,301,403 |
Match status codes |
-ms <size> |
Match response size |
-mw <words> |
Match word count |
-ml <lines> |
Match line count |
-mr <regex> |
Match regex in body |
Filters (hide results)
| Option |
Description |
-fc 404,500 |
Filter status codes |
-fs <size> |
Filter response size |
-fw <words> |
Filter word count |
-fl <lines> |
Filter line count |
-fr <regex> |
Filter regex |
-ac |
Autocalibrate filters |
Performance
| Option |
Description |
-t <n> |
Threads (default 40) |
-rate <n> |
Requests per second |
-timeout <sec> |
Request timeout |
-p <delay> |
Delay between requests |
Output
| Option |
Description |
-o <file> |
Output file |
-of json |
Output format (json, csv, html, md) |
-v |
Verbose (show redirects) |
Recipes
Directory Discovery
# Basic directory scan
ffuf -u https://target.com/FUZZ \
-w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt \
-mc 200,204,301,302,307,401,403 -t 50
# With extensions (files)
ffuf -u https://target.com/FUZZ \
-w /usr/share/seclists/Discovery/Web-Content/raft-medium-files.txt \
-e .php,.asp,.aspx,.jsp,.txt,.bak,.old,.zip \
-mc 200,204,301,302,307,401,403
# Recursive discovery
ffuf -u https://target.com/FUZZ \
-w wordlist.txt -recursion -recursion-depth 2
# Filter noise (custom 404 pages)
ffuf -u https://target.com/FUZZ -w wordlist.txt \
-fc 404 -fs 1543 -fw 200
Virtual Host Discovery
# Subdomain/vhost discovery
ffuf -u http://10.10.10.10 \
-H "Host: FUZZ.target.com" \
-w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt \
-fs 0 -mc 200,301,302,401,403
# With autocalibrate
ffuf -u http://10.10.10.10 \
-H "Host: FUZZ.target.com" \
-w subdomains.txt -ac
Parameter Discovery
# GET parameter names
ffuf -u https://target.com/page?FUZZ=test \
-w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt \
-mc 200,302 -fs 1234
# POST parameter names
ffuf -u https://target.com/api \
-X POST -H "Content-Type: application/x-www-form-urlencoded" \
-d "FUZZ=test" \
-w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt
# Parameter value fuzzing (IDOR)
ffuf -u https://target.com/user?id=FUZZ \
-w /usr/share/seclists/Fuzzing/4-digits-0000-9999.txt \
-mc 200 -rate 100
POST Data Fuzzing
# Login form fuzzing
ffuf -u https://target.com/login \
-X POST -H "Content-Type: application/x-www-form-urlencoded" \
-d "username=admin&password=FUZZ" \
-w /usr/share/seclists/Passwords/Common-Credentials/10k-most-common.txt \
-fc 401 -fs 1234
# JSON API fuzzing
ffuf -u https://target.com/api/login \
-X POST -H "Content-Type: application/json" \
-d '{"user":"admin","pass":"FUZZ"}' \
-w passwords.txt -mc 200
Multi-Position Fuzzing
# Username + password (clusterbomb = all combinations)
ffuf -u https://target.com/login \
-X POST -d "user=USER&pass=PASS" \
-w users.txt:USER -w passes.txt:PASS \
-mode clusterbomb -fc 401
# Path + extension (pitchfork = parallel)
ffuf -u https://target.com/PATHFUZZ.EXTFUZZ \
-w paths.txt:PATHFUZZ -w extensions.txt:EXTFUZZ \
-mode pitchfork
Through Proxy (Burp/Caido)
ffuf -u https://target.com/FUZZ \
-w wordlist.txt \
-x http://127.0.0.1:8080 \
-mc 200,301,403
Output & Parsing
# JSON output (best for parsing)
ffuf -u https://target.com/FUZZ -w wordlist.txt -of json -o results.json
# Parse JSON results
cat results.json | jq -r '.results[].url'
# CSV for spreadsheets
ffuf -u https://target.com/FUZZ -w wordlist.txt -of csv -o results.csv
# HTML report
ffuf -u https://target.com/FUZZ -w wordlist.txt -of html -o results.html
Troubleshooting
| Issue |
Solution |
| Everything matches |
Use -ac or filter by size/words -fs/-fw |
| Rate limited/blocked |
Reduce -rate, add -p delay |
| Proxy issues |
Check proxy config, use -k for TLS errors |
| Too many redirects |
Remove -r to see raw responses |
References