FFUF - Fuzz Faster U Fool
Cheatsheet
# Directory fuzzing
ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ -u http://<IP>:<PORT>/FUZZ
# Directory fuzzing (common.txt - faster)
ffuf -w /usr/share/seclists/Discovery/Web-Content/common.txt:FUZZ -u http://<IP>:<PORT>/FUZZ
# Extension fuzzing
ffuf -w /usr/share/seclists/Discovery/Web-Content/web-extensions.txt:FUZZ -u http://<IP>:<PORT>/indexFUZZ
# Page fuzzing (known extension)
ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ -u http://<IP>:<PORT>/blog/FUZZ.php
# Recursive fuzzing (dirs + .php pages, depth 1)
ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ -u http://<IP>:<PORT>/FUZZ -recursion -recursion-depth 1 -e .php -v
# Subdomain fuzzing
ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt:FUZZ -u http://FUZZ.<DOMAIN>/ -v
# VHost fuzzing (filter by response size)
ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt:FUZZ -u http://<DOMAIN>:<PORT>/ -H 'Host: FUZZ.<DOMAIN>' -fs <SIZE>
# GET parameter fuzzing
ffuf -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt:FUZZ -u http://<IP>:<PORT>/admin/admin.php?FUZZ=key -fs <SIZE>
# POST parameter fuzzing
ffuf -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt:FUZZ -u http://<IP>:<PORT>/admin/admin.php -X POST -d 'FUZZ=key' -H 'Content-Type: application/x-www-form-urlencoded' -fs <SIZE>
# POST value fuzzing
ffuf -w ids.txt:FUZZ -u http://<IP>:<PORT>/admin/admin.php -X POST -d 'id=FUZZ' -H 'Content-Type: application/x-www-form-urlencoded' -fs <SIZE>
# Multi-wordlist brute force (username:password)
ffuf -w users.txt:W1,/usr/share/seclists/Passwords/Common-Credentials/10-million-password-list-top-100.txt:W2 -X POST -d 'username=W1&password=W2' -H 'Content-Type: application/x-www-form-urlencoded' -u http://<IP>:<PORT>/login -fc 200
# Filter by status code
ffuf -w <WORDLIST>:FUZZ -u http://<IP>:<PORT>/FUZZ -fc 403,404
# Filter by response size
ffuf -w <WORDLIST>:FUZZ -u http://<IP>:<PORT>/FUZZ -fs <SIZE>
# Filter by word count
ffuf -w <WORDLIST>:FUZZ -u http://<IP>:<PORT>/FUZZ -fw <COUNT>
# Filter by line count
ffuf -w <WORDLIST>:FUZZ -u http://<IP>:<PORT>/FUZZ -fl <COUNT>
# Match only specific status codes
ffuf -w <WORDLIST>:FUZZ -u http://<IP>:<PORT>/FUZZ -mc 200,301
# Increase threads (default 40)
ffuf -w <WORDLIST>:FUZZ -u http://<IP>:<PORT>/FUZZ -t 100
# Output results to file
ffuf -w <WORDLIST>:FUZZ -u http://<IP>:<PORT>/FUZZ -o results.json -of json
# Add cookies / auth headers
ffuf -w <WORDLIST>:FUZZ -u http://<IP>:<PORT>/FUZZ -H 'Cookie: session=<COOKIE>' -H 'Authorization: Bearer <TOKEN>'
# Rate limiting (requests per second)
ffuf -w <WORDLIST>:FUZZ -u http://<IP>:<PORT>/FUZZ -rate 100# Generate sequential number wordlist
for i in $(seq 1 1000); do echo $i >> ids.txt; done
# Add domain to /etc/hosts
sudo sh -c 'echo "<IP> <DOMAIN>" >> /etc/hosts'
# Verify with curl after fuzzing a POST param
curl http://<IP>:<PORT>/admin/admin.php -X POST -d 'id=<VALUE>' -H 'Content-Type: application/x-www-form-urlencoded'Methodology
[!IMPORTANT] Follow this checklist whenever you need to fuzz a web application. Adapt scope based on what you already know about the target.
Phase 1: Directory & File Discovery
- Add target domain to
/etc/hostsif needed:sudo sh -c 'echo "<IP> <DOMAIN>" >> /etc/hosts' - Run directory fuzzing with
common.txtfirst (fast):ffuf -w .../common.txt:FUZZ -u http://<IP>/FUZZ - Run again with
directory-list-2.3-small.txtfor deeper coverage - Identify the web server/framework (Apache=
.php, IIS=.asp/.aspx, Tomcat=.jsp, nginx=check both) - Fuzz for extensions:
ffuf -w .../web-extensions.txt:FUZZ -u http://<IP>/indexFUZZ - Fuzz discovered directories for pages:
ffuf -w ...:FUZZ -u http://<IP>/<DIR>/FUZZ.<EXT> - Run recursive fuzzing on interesting directories: add
-recursion -recursion-depth 1 -e .php - Check for backup/config files: try extensions
.bak,.old,.conf,.config,.txt,.zip,.tar.gz
Phase 2: VHost & Subdomain Discovery
- Fuzz subdomains:
ffuf -w .../subdomains-top1million-5000.txt:FUZZ -u http://FUZZ.<DOMAIN>/ - Fuzz VHosts:
ffuf ... -H 'Host: FUZZ.<DOMAIN>'— do a dry run first to find the default response size, then add-fs <SIZE>to filter it out - Add any discovered VHosts/subdomains to
/etc/hosts - Repeat directory/file fuzzing on each new VHost/subdomain
Phase 3: Parameter Discovery
- Fuzz GET parameters on interesting pages:
ffuf -w .../burp-parameter-names.txt:FUZZ -u http://<IP>/page.php?FUZZ=key -fs <SIZE> - Fuzz POST parameters:
ffuf ... -X POST -d 'FUZZ=key' -H 'Content-Type: application/x-www-form-urlencoded' -fs <SIZE> - Fuzz discovered parameter values with custom or sequential wordlists
- Check for IDOR by fuzzing parameter values (
id=1,id=2, etc.)
Phase 4: Authentication Brute Force
- If a login form is found, fuzz credentials:
ffuf -w users.txt:W1,passwords.txt:W2 -X POST -d 'username=W1&password=W2' ... - Filter out failed login responses by status code (
-fc 200) or response size (-fs <SIZE>) - Try default credentials before brute forcing
Phase 5: Filtering & Tuning
- If results are noisy, identify the default response size/word count/line count from the output
- Apply appropriate filters:
-fs(size),-fw(words),-fl(lines),-fc(status code) - If rate-limited, slow down with
-rate <N>or reduce threads with-t <N>
Wordlists Reference
| Purpose | Path |
|---|---|
| Directory/page discovery | /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt |
| Quick directory scan | /usr/share/seclists/Discovery/Web-Content/common.txt |
| Extension discovery | /usr/share/seclists/Discovery/Web-Content/web-extensions.txt |
| Subdomain/VHost brute force | /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt |
| Parameter names | /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt |
| Larger directory list | /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt |
[!TIP] Pentest Tip: SecLists may be at
/opt/useful/seclists/on HTB PwnBox or/usr/share/seclists/on Kali/Parrot. Uselocate secliststo find the base path on your system.
Web Server Extension Mapping
| Server / Framework | Common Extensions |
|---|---|
| Apache + PHP | .php, .phps, .php7 |
| IIS | .asp, .aspx, .config |
| Tomcat / Java | .jsp, .do, .action |
| Python (Flask/Django) | Extensionless routes — fuzz directories instead |
| Node.js | Extensionless routes — fuzz directories instead |
[!TIP] Pentest Tip: Check the
ServerandX-Powered-Byresponse headers to identify the tech stack before fuzzing extensions.curl -I http://<IP>gives you this instantly.
Matcher & Filter Options
Matchers select responses that match the criteria (whitelist). Filters remove responses that match the criteria (blacklist).
Matchers (-m*)
| Flag | Matches On |
|---|---|
-mc | HTTP status codes — default: 200-299,301,302,307,401,403,405,500 |
-ms | Response size (bytes) |
-mw | Word count |
-ml | Line count |
-mr | Regex pattern in response body |
-mt | Time to first byte (ms) — >100 or <100 |
-mmode | Combine matchers with and / or (default: or) |
Filters (-f*)
| Flag | Filters On |
|---|---|
-fc | HTTP status codes |
-fs | Response size (bytes) |
-fw | Word count |
-fl | Line count |
-fr | Regex pattern in response body |
-ft | Time to first byte (ms) |
-fmode | Combine filters with and / or (default: or) |
[!TIP] Pentest Tip: For VHost/subdomain fuzzing, always do a test request first to see the default response size, then use
-fs <SIZE>to filter out false positives. Same approach works with-fwand-fl.
Multi-Keyword Fuzzing
FFUF supports multiple wordlists with separate keywords. Each wordlist is assigned a keyword with wordlist:KEYWORD syntax.
# Clusterbomb mode (all combinations) — W1 x W2
ffuf -w users.txt:W1 -w passwords.txt:W2 -X POST -d 'username=W1&password=W2' -H 'Content-Type: application/x-www-form-urlencoded' -u http://<IP>/login -fc 200[!CAUTION] OPSEC Warning: Multi-wordlist fuzzing generates
wordlist1_size × wordlist2_sizerequests. A 1000-user list with a 1000-password list = 1,000,000 requests. Use small, targeted lists and consider rate limiting with-rate.
Output Formats
# JSON output (most useful for parsing)
ffuf -w <WORDLIST>:FUZZ -u http://<IP>/FUZZ -o results.json -of json
# CSV output
ffuf -w <WORDLIST>:FUZZ -u http://<IP>/FUZZ -o results.csv -of csv
# HTML report
ffuf -w <WORDLIST>:FUZZ -u http://<IP>/FUZZ -o results.html -of htmlUseful Flags Reference
| Flag | Purpose |
|---|---|
-w | Wordlist path (:KEYWORD to name the fuzz position) |
-u | Target URL with FUZZ keyword |
-H | Add/replace HTTP header |
-X | HTTP method (GET, POST, PUT, etc.) |
-d | POST data body |
-t | Number of concurrent threads (default: 40) |
-rate | Maximum requests per second |
-recursion | Enable recursive directory fuzzing |
-recursion-depth | Max recursion depth |
-e | Comma-separated list of extensions to append |
-v | Verbose output (shows full URL and redirect location) |
-o | Output file path |
-of | Output format (json, csv, html, md, ejson, all) |
-ic | Ignore comments in wordlist (lines starting with #) |
-timeout | HTTP request timeout in seconds (default: 10) |
-se | Stop on spurious errors (too many false results) |
-sf | Stop when >95% of responses match a filter |
-ac | Auto-calibrate filtering (detect and filter default responses) |
[!TIP] Pentest Tip: The
-ac(auto-calibrate) flag is excellent for VHost and parameter fuzzing. FFUF automatically detects the default response pattern and filters it, saving you from manually finding the size/word count to filter.
#cpts #oscp #web #enumeration #tools #methodology