WarFi Labs

ffuf

web fuzzer ยท MIT

A fast web fuzzer for finding hidden directories, files, parameters, and virtual hosts by swapping a wordlist into any part of a request.

Authorized use only. Run these only on systems you own or have explicit written permission to test. Full notice at the foot of the page.

01Fuzzing, the one idea behind ffuf

ffuf does one thing and does it fast: it takes a request with the marker FUZZ somewhere in it, and replaces that marker with every line of a wordlist, watching how the responses differ. Put FUZZ in the path and you are finding hidden directories; put it in a parameter name and you are discovering parameters; put it in the Host header and you are enumerating virtual hosts. The skill is less about the tool and more about where you place FUZZ and how you filter the noise.

↑ contents

02Install

$ sudo emerge net-analyzer/ffuf # Gentoo

$ sudo apt install ffuf # Debian / Kali

$ sudo dnf install ffuf # Fedora

$ go install github.com/ffuf/ffuf/v2@latest # any distro (Go)

03Directory and file discovery

The bread-and-butter run: FUZZ in the URL path, a content-discovery wordlist, and you find what is not linked anywhere. SecLists is the usual source of wordlists. Add -e to append extensions when hunting files.

$ ffuf -u https://target/FUZZ -w /usr/share/seclists/Discovery/Web-Content/common.txt

$ ffuf -u https://target/FUZZ -w common.txt -e .php,.bak,.old,.txt

/'___\ /'___\ /'___\ /\ \__/ /\ \__/ __ __ /\ \__/ \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\ \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/ \ \_\ \ \_\ \ \____/ \ \_\ \/_/ \/_/ \/___/ \/_/ v2.1.0 admin [Status: 301, Size: 169, Words: 5, Lines: 8] login [Status: 200, Size: 2048, Words: 102, Lines: 56] .git [Status: 301, Size: 169, Words: 5, Lines: 8] backup.old [Status: 200, Size: 51204, Words: 1, Lines: 1]

04Filtering noise, the real skill

A site that returns 200 for everything, or a custom 404 page, will flood you with false hits. The fix is to filter or match by status, size, word count, or line count. Match the one thing that is interesting, or filter out the size of the standard not-found page. Getting this right is what separates a usable run from a screenful of garbage.

$ ffuf -u https://target/FUZZ -w common.txt -mc 200,301,302,403

$ ffuf -u https://target/FUZZ -w common.txt -fs 1234

$ ffuf -u https://target/FUZZ -w common.txt -fc 404 -ac

/'___\ /'___\ /'___\ /\ \__/ /\ \__/ __ __ /\ \__/ \ \ \ \ \ \ /\ \/\ \ \ \ \ \ \_\ \ \_\ \ \____/ \ \_\ \/_/ \/_/ \/___/ \/_/ v2.1.0 ________________________________________________ admin [Status: 301, Size: 169, Words: 5, Lines: 8] login [Status: 200, Size: 2314, Words: 541, Lines: 102] config.bak [Status: 200, Size: 1200, Words: 98, Lines: 21] :: Progress: [4700/4700] :: Job [1/1] :: 420 req/sec :: Errors: 0 ::

» -fs filters a response size, -fc filters a status code, and -ac auto-calibrates by learning the junk response first. Reach for -ac when a site has a soft 404.

05Discovering parameters

Hidden parameters are where logic flaws and injection often hide. Put FUZZ in the query string as a parameter name and filter out the baseline response size to find parameters the app quietly honours.

$ ffuf -u 'https://target/page?FUZZ=test' -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt -fs 2048

id [Status: 200, Size: 2048, Words: 410, Lines: 77] q [Status: 200, Size: 2048, Words: 410, Lines: 77] debug [Status: 200, Size: 5213, Words: 904, Lines: 171] :: Progress: [2588/2588] :: Job [1/1] :: 512 req/sec :: Errors: 0 :: (debug returns a larger response than the 2048-byte baseline, so it slips past -fs and stands out as a real parameter)

06Virtual host enumeration

One IP often serves many sites by the Host header. Fuzz the Host header to find virtual hosts that are not in DNS, which can expose staging or internal apps hiding behind the same server.

$ ffuf -u https://target/ -H 'Host: FUZZ.target.com' -w subdomains.txt -fs 169

admin [Status: 200, Size: 3310, Words: 620, Lines: 98] internal [Status: 200, Size: 2890, Words: 540, Lines: 88] :: Progress: [1000/1000] :: Job [1/1] :: 480 req/sec :: Errors: 0 ::

↑ contents

07Things people miss

» Use -recursion to dive into directories it finds, with -recursion-depth to keep it sane.

» Rate-limit with -rate on fragile targets so you do not knock the app over; -p adds a delay.

» POST fuzzing: -X POST -d 'user=FUZZ' fuzzes form fields, not just URLs.

» Save machine-readable output with -o result.json -of json for later processing.

08Reading ffuf results as the owner

Run ffuf against your own app and the hits are your exposure: a .git directory serving source, a backup.old with last year's config, an admin panel you forgot was reachable. Each one is something to remove or lock down. The filtering skill matters defensively too: a custom 404 that returns 200 hides real problems from you as much as from an attacker.

» Remove source-control and backup files from web roots; .git and .bak are classic leaks ffuf finds instantly.

» Return a real 404 status for missing pages so discovery is harder and your own scans are cleaner.

» Put admin and staging interfaces behind authentication or a VPN, not just an unlinked URL.

↑ contents

Authorized use only

The tools and techniques in these guides are for defending, testing, and understanding systems you own or have explicit written permission to assess. Unauthorized access to computers, networks, accounts, or data is a criminal offense in nearly every jurisdiction, and the penalties are real.

A few of the laws that apply, by way of example:

Wherever you are, the rule is the same: get authorization in writing, stay within the agreed scope, and never touch a system that is not yours to test. If you are unsure whether something is permitted, treat it as not permitted until you have clear authorization.

This is general information, not legal advice.