ffuf — Complete Reference
What is ffuf?
Fast F web Fuzzer — Go-based CLI that injects wordlist entries wherever FUZZ appears in URL, headers, or body. Primary Gobuster alternative when you need filter by size/words/lines, Host header vhosts, parameter fuzzing, or multi-wordlist attacks.
OSCP use: Wildcard 200 responses (
-fs), vhost discovery (-H "Host: FUZZ"), hidden GET/POST params, extension brute (-e), recursion on found dirs.
Install (Kali)
sudo apt update && sudo apt install -y ffuf
# or: go install github.com/ffuf/ffuf/v2@latestVerify: ffuf -V
Full install index → Installation - Kali Setup
📌 Template
ffuf -w /usr/share/wordlists/dirb/big.txt -u http://TARGET/FUZZ \
-e .php,.txt,.html,.bak -c -v -o ffuf_big.txt📌 Kali Wordlists — Quick Index
| Attack | Path |
|---|---|
| Dir — quick | /usr/share/wordlists/dirb/common.txt |
| Dir — medium | /usr/share/wordlists/dirb/big.txt |
| Dir — thorough | /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt |
| Dir — SecLists | /usr/share/seclists/Discovery/Web-Content/raft-medium-words.txt |
| Vhost / subdomain | /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt |
| GET/POST params | /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt |
| Passwords | /usr/share/wordlists/rockyou.txt |
| API | /usr/share/seclists/Discovery/Web-Content/api/api-endpoints.txt |
| Backups / .db | /usr/share/seclists/Discovery/Web-Content/Common-DB-Backups.txt |
ls /usr/share/wordlists/dirb/ /usr/share/seclists/Discovery/Web-Content/ /usr/share/seclists/Discovery/DNS/
sudo apt install seclists wordlistsBasic Syntax
ffuf -w WORDLIST -u http://TARGET/FUZZFUZZ = injection point. Custom keyword: -w /path/list:KEYWORD then use KEYWORD in URL.
📌 1) HTTP Options
| Flag | Description |
|---|---|
-u URL | Target URL — must contain FUZZ (or custom keyword) |
-X METHOD | HTTP method (GET, POST, PUT, DELETE, etc.) |
-H "Name: Value" | Header (repeatable). e.g. -H "Host: FUZZ.domain.com" |
-b "COOKIES" | Cookie string NAME=VAL; NAME2=VAL2 |
-d DATA | POST body — use FUZZ in data |
-r | Follow redirects |
-raw | Do not encode URI |
-http2 | Use HTTP/2 |
-ignore-body | Don’t fetch response body (faster) |
-timeout SEC | Request timeout (default 10) |
-x PROXY | Proxy: http://127.0.0.1:8080 or socks5://127.0.0.1:9050 |
-replay-proxy URL | Replay matches through another proxy |
-sni NAME | TLS SNI (no FUZZ support) |
-cc FILE | Client certificate |
-ck FILE | Client key |
-recursion | Recurse into found dirs — URL must end in FUZZ |
-recursion-depth N | Max recursion depth (default 0) |
-recursion-strategy | default (redirect) or greedy (all matches) |
📌 2) Matcher Options (-m*)
Only show responses matching criteria:
| Flag | Description |
|---|---|
-mc CODES | Match status codes — default 200-299,301,302,307,401,403,405,500 · use all |
-ms SIZE | Match response size (bytes) |
-mw COUNT | Match word count |
-ml COUNT | Match line count |
-mr REGEX | Match regex in response body |
-mt TIME | Match time to first byte — >100 or <100 ms |
-mmode | Matcher operator: and or or (default or) |
ffuf -w /usr/share/wordlists/dirb/common.txt -u http://TARGET/FUZZ -mc 200,301,403
ffuf -w /usr/share/wordlists/dirb/common.txt -u http://TARGET/FUZZ -mc all -mr "admin"📌 3) Filter Options (-f*) — Wildcard Bypass
Hide false positives (OSCP essential):
| Flag | Description |
|---|---|
-fc CODES | Filter status codes — e.g. -fc 404 |
-fs SIZE | Filter response size — e.g. -fs 1234 |
-fw COUNT | Filter word count |
-fl COUNT | Filter line count |
-fr REGEX | Filter regex in body |
-ft TIME | Filter by response time |
-fmode | Filter operator: and or or (default or) |
Wildcard 200 workflow:
# Baseline size from fake path
curl -s http://TARGET/nonexistent999 | wc -c
ffuf -w /usr/share/wordlists/dirb/common.txt -u http://TARGET/FUZZ -fs 1234
# Or auto-calibrate
ffuf -w /usr/share/wordlists/dirb/common.txt -u http://TARGET/FUZZ -ac| Auto-calibrate | Description |
|---|---|
-ac | Auto-calibrate filtering |
-acc STRING | Custom calibration string (implies -ac) |
-ach | Per-host autocalibration |
-ack KEYWORD | Autocalibration keyword (default FUZZ) |
-acs STRATEGY | Custom autocalibration strategy |
📌 4) Input / Wordlist Options
| Flag | Description |
|---|---|
-w FILE | Wordlist — path:KEYWORD for custom keyword |
-e EXT | Extensions comma-separated — .php,.txt,.html |
-D | DirSearch wordlist mode (with -e) |
-enc 'FUZZ:urlencode' | Encode keyword — b64encode, etc. |
-ic | Ignore wordlist comments |
-mode MODE | Multi-wordlist mode: clusterbomb, pitchfork, sniper |
-request FILE | Raw HTTP request file (FUZZ in file) |
-request-proto | Protocol for raw request (default https) |
-input-cmd CMD | External command produces payloads — uses $FFUF_NUM |
-input-num N | Number of inputs for -input-cmd |
-input-shell SHELL | Shell for input command |
Multi-wordlist modes
| Mode | Behavior |
|---|---|
| clusterbomb | Cartesian product — all combos (default) |
| pitchfork | Parallel — word 1 + word 1, word 2 + word 2… |
| sniper | One payload at a time across multiple positions |
# Two wordlists — PARAM and VAL
ffuf -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt:PARAM \
-w /usr/share/wordlists/dirb/common.txt:VAL \
-u "http://TARGET/?PARAM=VAL" -mr "VAL"📌 5) General / Performance Options
| Flag | Description |
|---|---|
-t N | Threads (default 40) |
-p SEC | Delay between requests — 0.1 or 0.1-2.0 |
-rate N | Max requests per second |
-maxtime SEC | Max total runtime |
-maxtime-job SEC | Max time per recursion job |
-c | Color output |
-v | Verbose — full URL + redirect |
-s | Silent — results only |
-json | JSONL output |
-config FILE | Load config file |
-V | Version |
-noninteractive | Disable interactive mode |
-sa | Stop on all errors |
-sf | Stop if >95% responses are 403 |
-se | Stop on spurious errors |
-search HASH | Search ffuf history |
📌 6) Output Options
| Flag | Description |
|---|---|
-o FILE | Output file |
-of FORMAT | json, ejson, html, md, csv, ecsv, all |
-od DIR | Directory for matched results |
-or | Don’t create output if no results |
-debug-log FILE | Internal debug log |
📌 7) Fuzzing Recipes (OSCP)
Directory / file discovery
Wordlists: quick → /usr/share/wordlists/dirb/common.txt · medium → dirb/big.txt · thorough → /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
ffuf -w /usr/share/wordlists/dirb/common.txt -u http://TARGET/FUZZ
ffuf -w /usr/share/wordlists/dirb/big.txt -u http://TARGET/FUZZ \
-e .php,.txt,.html,.bak -c -v
ffuf -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt \
-u http://TARGET/FUZZ -e .php,.txt,.html,.bak -c -v
ffuf -w /usr/share/seclists/Discovery/Web-Content/raft-medium-words.txt \
-u https://TARGET/FUZZ -k -ac
ffuf -w /usr/share/seclists/Discovery/Web-Content/Common-DB-Backups.txt \
-u http://TARGET/FUZZ -e .db,.sql,.bak,.zipVhost (Host header)
Wordlists: /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt · larger → ...-20000.txt · Jhaddix → /usr/share/seclists/Discovery/DNS/dns-Jhaddix.txt
ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt \
-u http://TARGET -H "Host: FUZZ.target.htb" -fs 4242
ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt \
-u https://TARGET -H "Host: FUZZ" -k -mc 200
ffuf -w /usr/share/seclists/Discovery/DNS/dns-Jhaddix.txt \
-u http://10.10.10.10 -H "Host: FUZZ.htb" -acGET parameter name / value
Wordlists: param names → /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt · values → /usr/share/wordlists/dirb/common.txt or rockyou.txt (passwords)
ffuf -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt \
-u "http://TARGET/page.php?FUZZ=test" -fs 4242
ffuf -w /usr/share/wordlists/dirb/common.txt \
-u "http://TARGET/page.php?id=FUZZ" -fc 401
# Authenticated admin param discovery (streamio-style)
ffuf -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt \
-u 'https://streamio.htb/admin/?FUZZ=' \
-b PHPSESSID=hcdd0gnsrol8opisb09o09b9ah --fs 1678POST fuzzing
Wordlists: passwords → /usr/share/wordlists/rockyou.txt · usernames → /usr/share/seclists/Usernames/top-usernames-shortlist.txt
ffuf -w /usr/share/wordlists/rockyou.txt -u http://TARGET/login.php -X POST \
-d "username=admin&password=FUZZ" -H "Content-Type: application/x-www-form-urlencoded" -fc 401
ffuf -w /usr/share/wordlists/dirb/common.txt -u http://TARGET/api -X POST \
-H "Content-Type: application/json" \
-d '{"user":"FUZZ"}' -fr "error"Authenticated
ffuf -w /usr/share/wordlists/dirb/common.txt -u http://TARGET/FUZZ -b "PHPSESSID=abc123"
ffuf -w /usr/share/wordlists/dirb/big.txt -u http://admin:pass@TARGET/FUZZBurp / raw request
# Save request from Burp, replace value with FUZZ
ffuf -request request.txt \
-w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txtRecursive
ffuf -w /usr/share/wordlists/dirb/common.txt -u http://TARGET/FUZZ \
-recursion -recursion-depth 2 -fc 404Through proxy (Burp)
ffuf -w /usr/share/wordlists/dirb/common.txt -u http://TARGET/FUZZ -x http://127.0.0.1:8080📌 8) Interactive Mode
Press ENTER during scan → adjust filters live:
fc [code] - filter status
fs [size] - filter size
fw [words] - filter words
fl [lines] - filter lines
show - show current matches
restart - restart job
savejson f - save matches
help
ENTER - resume
📌 WebSockets — discovery (HTTP only)
ffuf does not speak WebSocket frames — it fuzzes HTTP URLs, headers, and bodies. Use it to find WebSocket endpoints and upgrade paths, then test messages in Burp Suite or Curl.
Fuzz common WebSocket paths
ffuf -w /usr/share/seclists/Discovery/Web-Content/raft-medium-words.txt \
-u http://TARGET/FUZZ -e .ws,.socket -fc 404 -c
ffuf -w /usr/share/seclists/Discovery/Web-Content/api/api-endpoints.txt \
-u http://TARGET/FUZZ -c
# look for: /ws, /websocket, /socket.io, /cable, /graphql → **[[GraphQL]]**, /api/wsFuzz HTTP upgrade / handshake endpoint
Some apps expose WS on a path that returns 101 Switching Protocols only with correct headers:
ffuf -w /usr/share/wordlists/dirb/common.txt \
-u http://TARGET/FUZZ \
-H "Connection: Upgrade" -H "Upgrade: websocket" \
-H "Sec-WebSocket-Version: 13" -H "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==" \
-mc 101,200,400,403 -cFuzz REST APIs that front WebSocket apps
SPAs often use HTTP login → token → first WS message. Fuzz HTTP params and JSON bodies; SQLi may live in WS messages instead:
ffuf -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt \
-u "http://TARGET/api?FUZZ=1" -fs 0 -cAfter finding /ws or similar → Burp Suite WebSockets history → manual SQLi → SQLMap via local HTTP bridge.
📌 9) ffuf vs Gobuster
| Situation | Tool |
|---|---|
| Simple dir brute, clean 404 | Gobuster |
| Wildcard same-size 200 | ffuf -fs / -ac |
| Vhost / Host header | ffuf |
| Multi-param / clusterbomb | ffuf |
| DNS subdomain brute | Gobuster dns |
| Raw Burp request | ffuf -request |
📌 Quick Cheat Sheet
# Dir — common wordlist
ffuf -w /usr/share/wordlists/dirb/common.txt -u http://TARGET/FUZZ -fs 1234 -c
ffuf -w /usr/share/wordlists/dirb/common.txt -u http://TARGET/FUZZ -ac
# Vhost
ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt \
-u http://TARGET -H "Host: FUZZ.htb" -fs 4242
# Dir + extensions + recursion
ffuf -w /usr/share/wordlists/dirb/big.txt -u http://TARGET/FUZZ \
-e .php,.txt -recursion -recursion-depth 1
# Burp proxy
ffuf -w /usr/share/wordlists/dirb/common.txt -u http://TARGET/FUZZ \
-x http://127.0.0.1:8080 -mc 200,301,403
# Raw Burp request + param wordlist
ffuf -request req.txt \
-w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt -fc 404