Skip to Content

Site is under construction if theres any issues, please contact me at

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/hosts if needed: sudo sh -c 'echo "<IP> <DOMAIN>" >> /etc/hosts'
  • Run directory fuzzing with common.txt first (fast): ffuf -w .../common.txt:FUZZ -u http://<IP>/FUZZ
  • Run again with directory-list-2.3-small.txt for 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

PurposePath
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. Use locate seclists to find the base path on your system.


Web Server Extension Mapping

Server / FrameworkCommon Extensions
Apache + PHP.php, .phps, .php7
IIS.asp, .aspx, .config
Tomcat / Java.jsp, .do, .action
Python (Flask/Django)Extensionless routes — fuzz directories instead
Node.jsExtensionless routes — fuzz directories instead

[!TIP] Pentest Tip: Check the Server and X-Powered-By response 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*)

FlagMatches On
-mcHTTP status codes — default: 200-299,301,302,307,401,403,405,500
-msResponse size (bytes)
-mwWord count
-mlLine count
-mrRegex pattern in response body
-mtTime to first byte (ms) — >100 or <100
-mmodeCombine matchers with and / or (default: or)

Filters (-f*)

FlagFilters On
-fcHTTP status codes
-fsResponse size (bytes)
-fwWord count
-flLine count
-frRegex pattern in response body
-ftTime to first byte (ms)
-fmodeCombine 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 -fw and -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_size requests. 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 html

Useful Flags Reference

FlagPurpose
-wWordlist path (:KEYWORD to name the fuzz position)
-uTarget URL with FUZZ keyword
-HAdd/replace HTTP header
-XHTTP method (GET, POST, PUT, etc.)
-dPOST data body
-tNumber of concurrent threads (default: 40)
-rateMaximum requests per second
-recursionEnable recursive directory fuzzing
-recursion-depthMax recursion depth
-eComma-separated list of extensions to append
-vVerbose output (shows full URL and redirect location)
-oOutput file path
-ofOutput format (json, csv, html, md, ejson, all)
-icIgnore comments in wordlist (lines starting with #)
-timeoutHTTP request timeout in seconds (default: 10)
-seStop on spurious errors (too many false results)
-sfStop when >95% of responses match a filter
-acAuto-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

Last updated on