Directory Fuzzing¶
Why Directory Fuzzing?¶
Web applications expose more than what's linked on the front page. Admin panels, backup directories, API endpoints, and development artifacts often exist at predictable paths — but they're not advertised. Directory fuzzing systematically tests path names from a wordlist against the server to find these hidden resources.
This is always your first fuzzing step because it gives you the broadest picture of the application's structure before you dive deeper into specific pages or parameters.
Basic Command¶
ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ -u http://SERVER_IP:PORT/FUZZ
This sends a GET request for each word in the list, replacing FUZZ in the URL path:
http://SERVER_IP:PORT/adminhttp://SERVER_IP:PORT/loginhttp://SERVER_IP:PORT/uploadshttp://SERVER_IP:PORT/backup- ... (87,650 entries in the small list)
Understanding the Output¶
ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ -u http://10.10.10.5:8080/FUZZ
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v2.1.0-dev
________________________________________________
:: Method : GET
:: URL : http://10.10.10.5:8080/FUZZ
:: Wordlist : FUZZ: /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 40
:: Matcher : Response status: 200,204,301,302,307,401,403,405,500
________________________________________________
forum [Status: 301, Size: 326, Words: 20, Lines: 10, Duration: 45ms]
blog [Status: 200, Size: 15842, Words: 3420, Lines: 312, Duration: 52ms]
admin [Status: 403, Size: 289, Words: 21, Lines: 11, Duration: 38ms]
Each result line contains:
| Column | Meaning |
|---|---|
| Word | The wordlist entry that produced a hit |
| Status | HTTP response code (200, 301, 403, etc.) |
| Size | Response body size in bytes |
| Words | Word count in the response body |
| Lines | Line count in the response body |
| Duration | Round-trip time for the request |
Default Matchers
By default, ffuf shows any response that does NOT return a 404. The full default match list is: 200, 204, 301, 302, 307, 401, 403, 405, 500. This means you'll also see 403 Forbidden directories — which are still valuable (confirms the path exists).
Filtering False Positives¶
Many applications return a custom "not found" page with a 200 status code instead of a proper 404. This floods your results with junk. Filtering is the most important skill in ffuf.
Filter by Status Code (-fc)¶
Remove responses with specific status codes:
# Filter out 403 Forbidden (you know they exist but can't access them yet)
ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ \
-u http://10.10.10.5:8080/FUZZ -fc 403
# Filter out multiple codes
ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ \
-u http://10.10.10.5:8080/FUZZ -fc 403,401,500
Filter by Response Size (-fs)¶
When the "not found" page always returns the same size, filter it out:
# First, send a request for a path that doesn't exist to get the baseline:
curl -s http://10.10.10.5:8080/thisdoesnotexist | wc -c
# Output: 4242
# Now filter that exact size:
ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ \
-u http://10.10.10.5:8080/FUZZ -fs 4242
Filter by Word Count (-fw)¶
When the "not found" page has a consistent word count:
ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ \
-u http://10.10.10.5:8080/FUZZ -fw 12
Filter by Line Count (-fl)¶
ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ \
-u http://10.10.10.5:8080/FUZZ -fl 10
Auto-Calibration
Use -ac to let ffuf auto-detect and filter the "noise" response. It sends random payloads before fuzzing, measures the baseline, and filters matching responses automatically:
Match-Only Mode (-mc)¶
Instead of filtering OUT what you don't want, specify ONLY the codes you want:
# Only show 200 OK responses
ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ \
-u http://10.10.10.5:8080/FUZZ -mc 200
Don't Over-Filter
Don't filter 301/302 redirects — they often point to valid directories that redirect to directory/ (with trailing slash). Status 403 also confirms existence. Filter aggressively only when you're drowning in false positives.
Rate Limiting and Threads¶
Threads (-t)¶
Ffuf defaults to 40 concurrent threads. Increase for faster results on stable targets, decrease to avoid detection or when the server is slow:
# Fast (100 threads) — use on exam labs
ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ \
-u http://10.10.10.5:8080/FUZZ -t 100
# Slow (5 threads) — for fragile/rate-limited servers
ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ \
-u http://10.10.10.5:8080/FUZZ -t 5
Rate Limiting (-rate)¶
Set a maximum number of requests per second (more precise than thread count):
# Max 100 requests/second
ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ \
-u http://10.10.10.5:8080/FUZZ -rate 100
Practical Examples¶
Example 1: Standard Engagement¶
# Step 1: Quick baseline check
curl -s -o /dev/null -w "%{http_code} %{size_download}" http://10.10.10.5:8080/nonexistentpath1234
# Output: 200 4242
# Step 2: Fuzz with size filter
ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ \
-u http://10.10.10.5:8080/FUZZ -fs 4242 -t 100
Example 2: Save Results for Later¶
ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ \
-u http://10.10.10.5:8080/FUZZ -fc 404 -o results.json -of json
Example 3: Verbose Mode with Redirects¶
ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ \
-u http://10.10.10.5:8080/FUZZ -fc 404 -v
Verbose mode shows the full URL and the redirect target (for 301/302), which helps you understand the application's routing.
Wordlist Selection¶
| Wordlist | Entries | Use Case |
|---|---|---|
directory-list-2.3-small.txt |
~87k | Quick initial scan |
directory-list-2.3-medium.txt |
~220k | Standard engagement |
directory-list-2.3-big.txt |
~1.3M | Thorough (slow) |
raft-medium-directories.txt |
~30k | Good alternative |
common.txt |
~4.7k | Ultra-fast first pass |
All located under /usr/share/seclists/Discovery/Web-Content/.
Revision Recap
- Directory fuzzing is your first step — it maps the application's top-level structure
- The basic pattern is
ffuf -w wordlist:FUZZ -u http://target/FUZZ - Always check for false positives — custom 200 pages that aren't real content
- Use
-fs(size),-fw(words),-fl(lines), or-fc(code) to filter noise -acauto-calibrates filtering for you- Adjust
-t(threads) and-rateto balance speed vs. stealth/stability - Save results with
-o results.json -of jsonfor later analysis
➡️ Next: Extension Fuzzing — determine the web technology stack