Fuzzers

Introduction

Plenty of TryHackMe rooms have a task like “find the hidden login page,” and the answer is the same ritual every time: throw a wordlist of paths at the web server and see what sticks. I had been switching tools based on whatever the room walkthrough used, so I sat down to pick a default.

I think there isn’t really any ‘default’. This post is what survived: gobuster, ffuf, and feroxbuster, plus the commands I use.

Why DirBuster didn’t make the cut

DirBuster was the old standard, and it still ships in Kali, but its last real release is over a decade old. It’s a Java GUI application with no maintainer and no security fixes, and the ZAP project absorbed its functionality years ago. The wordlists are the part worth keeping: the famous directory-list-2.3-*.txt files live on in /usr/share/wordlists/dirbuster/ and work fine in any modern tool.

What these tools do

All three do the same job: take a wordlist, request each entry as a path under a target URL, and report which responses look interesting. The differences live around that loop, in raw speed and in how each tool deals with noise.

Noise is the constant problem. Most servers answer garbage paths like /does-not-exist with a friendly 200 and a custom error page, a soft 404. A naive tool reports thousands of “found” pages, so the quality of a fuzzer is mostly the quality of its filtering.

Note on the below commands

The commands below run fast, some with -t 50, because I tested them against lab boxes where nothing minds. A public WordPress site (for instance) minds: running this post’s gobuster one-liner against a real WordPress install returned screenfuls of this:

aa.php               (Status: 429) [Size: 17]
aa                   (Status: 429) [Size: 17]
abc.php              (Status: 429) [Size: 17]

Status 429 means “too many requests”: a security plugin like Wordfence, CleanTalk or a WAF in front of the site, decided my scan was a scan. The giveaway is that every “hit” has the exact same size; that’s one block response, repeated. From the moment it starts, the results are worthless, because real pages get the same 429.

If the target is something you don’t own, throttle. Gobuster has no delay flag, so drop the threads (-t 5), ffuf takes -rate 20 for requests per second, and feroxbuster has --rate-limit 20. A browser user agent helps too (-a, -H "User-Agent: ...", or -A), since the default tool agents sit on plenty of blocklists, and a smaller wordlist keeps you under hourly caps. And if the 429s already started: stop, wait out the block, and rescan slower.

Filtering the status code away hides the symptom while the scan keeps finding nothing, so don’t do that either.

Contenders

The contenders with their core jobs.

gobusterffufferoxbuster
Current version (Sep 2026)v3.8.2v2.3.0v2.12.0
LanguageGoGoRust
Core jobMulti-mode brute forcerGeneric web fuzzerContent discovery specialist
Modesdir, dns, vhost, s3, gcs, fuzzAnything with a FUZZ placeholderHTTP directories and files, but all of it

Gobuster

Gobuster is the one I use when the question isn’t just “which directories exist.”

The dns mode enumerates subdomains, vhost hunts virtual hosts, and s3 and gcs probe cloud buckets. The flags are simple enough to remember, which matters at 11pm in a lab.

gobuster dir -u http://target.thm -w /usr/share/wordlists/dirb/common.txt -x php,html -t 50

Subdomains and virtual hosts:

gobuster dns -d target.thm -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt
gobuster vhost -u http://target.thm -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt --append-domain

Filtering is basic (status codes, size, a regex), recursion is coarse, and Kali’s apt package tends to lag behind the GitHub releases, sometimes by several minor versions. Check gobuster version before blaming the tool; grabbing the release binary fixes a lot of “missing flag” confusion.

Gobuster is the first tool I ever used for this purpose, and often the one I try first during an engagement.

ffuf

ffuf thinks in placeholders.

You give it a URL with the word FUZZ in it, and it replaces that word with every wordlist entry. The placeholder can go anywhere: in a path, in a header, in a POST body. Directory brute forcing is the special case where FUZZ lands after the slash.

ffuf -u http://target.thm/FUZZ -w /usr/share/wordlists/dirb/common.txt -e .php,.html -ac

-ac is auto-calibration: ffuf probes a few random paths first, learns what the soft 404 looks like, and filters matching responses automatically. When the target serves everything with the same status code, I filter on response size instead, or run a vhost hunt through the Host header:

ffuf -u http://target.thm/FUZZ -w common.txt -fc 403 -fs 14972
ffuf -u http://target.thm/ -H "Host: FUZZ.target.thm" -w subdomains.txt -fs 14972

Two wordlists at once turns it into a small cartography engine, and -o results.json -of json feeds whatever script comes next:

ffuf -u http://target.thm/FUZZ/FUZ2Z -w dirs.txt -w files.txt -ac -o results.json -of json

The learning curve is steeper: you have to think in placeholders, and the filter flags only help once you know which responses are noise. In exchange you get the fastest of the three and the easiest to script around.

I like this one especially for the speed and the uniform syntax.

feroxbuster

Feroxbuster does one job and does the whole job.

Recursion is on by default: find /admin, and it starts brute forcing /admin/ and deeper on its own, with sane limits you can tune. For the soft 404 problem it has my favorite filter of the three: point --filter-similar-to at a known garbage path and it drops every response that looks like it, similarity-compared rather than size-matched.

feroxbuster -u http://target.thm -w /usr/share/wordlists/dirb/common.txt -x php,html -d 2
feroxbuster -u http://target.thm -w common.txt --filter-similar-to http://target.thm/no-such-page-xyz

Multiple targets in one run, link extraction from discovered pages, a TOML config for repeated scans, and a --burp flag to mirror traffic through a proxy:

feroxbuster -u http://app1.thm http://app2.thm -w common.txt --extract-links

The limitation is the mirror image of its focus: no DNS mode, no parameter fuzzing, and JSON output that’s less scripting-friendly than ffuf’s. The docs are excellent, which I don’t get to say about CLI tools often.

I did not use feroxbuster before this post. Of course for the post I had to try stuff out and I find it a bit more cumbersome than the other two. I see the potential though and the docs are amazing.

Side by side

Let’s put it in a table.

gobusterffufferoxbuster
RecursionOpt-in, coarseOpt-in, flexibleOn by default, tunable
Soft 404 handlingManual filters-ac auto-calibration--filter-similar-to and friends
Filter onStatus, size, regexStatus, size, words, lines, regexStatus, size, words, lines, regex, similarity
Multiple targetsOne per runOne per processYes, one run
OutputPlain textJSON, CSV, MarkdownLive terminal, JSON log
Beyond directoriesdns, vhost, s3, gcsAnything fuzzleableNo

Which one I grab first

In practice, gobuster still wins on habit: the first tool I ever used for this job, with flags in muscle memory. My preference keeps drifting toward feroxbuster, because its defaults match how I want to work, but it feels more cumbersome than the other two, so I keep falling back to what my hands know. ffuf is the compromise I should commit to: the speed and uniform syntax I like, and the tool rooms and exam graders expect. Subdomains and vhosts remain gobuster territory either way.

All three are in the Kali repos. The shared asset underneath them is the wordlist collection: SecLists covers most situations once you apt install seclists.

Next

All three are healthy and actively maintained. Knowing which job calls for which one is the skill.

Hidden directories are more fun when there’s somewhere real to hunt. My red team lab just grew from two targets to five, and that rebuild is next week’s post.