> ## Documentation Index
> Fetch the complete documentation index at: https://0-x.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Directory & Subdomain Fuzzing

Fuzzing throws a wordlist at a target and watches what sticks, hidden directories, backup files, forgotten API endpoints, or subdomains that never show up in DNS records or Certificate Transparency logs. It's active (the target sees every request), but it's one of the highest value steps in web enumeration since almost nothing turns up by just browsing the site.

> **Directory / File Fuzzing**
>
> Brute-forcing paths and filenames on a known host (`FUZZ` replaces a URL segment). Finds hidden admin panels, backup files, and unlinked endpoints.

> **Subdomain / VHost Fuzzing**
>
> Brute-forcing hostnames instead, either against DNS (subdomain enumeration) or against a single IP's `Host` header (virtual host discovery). Finds hosts that were never in any public DNS record.

> [!TIP]
>
> Always run a passive subdomain pass first (see the [OSINT](https://0-x.dev/osint.md) and [Passive Information Gathering](https://0-x.dev/passive-information-gathering.md) pages) before fuzzing. It's free, quiet, and usually finds the easy wins; fuzzing is for what passive recon missed.

***

## FFUF

FFUF is fast, flexible, and the most commonly reached for fuzzer, it handles directories, files, parameters, POST bodies, and virtual hosts all through the same `FUZZ` keyword mechanic.

Basic directory fuzzing walks a wordlist against a path on the target.

```shellscript wrap theme={null}
ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -u http://TARGET_IP:PORT/FUZZ
```

File fuzzing targets a specific path and appends extensions, useful once you already know a directory exists and want to find files inside it.

```shellscript wrap theme={null}
ffuf -w /usr/share/seclists/Discovery/Web-Content/common.txt -u http://TARGET_IP:PORT/PATH/FUZZ.html -e .php,.html,.txt,.bak,.js -v
```

Recursive fuzzing automatically re-fuzzes any directory it finds, without having to manually re-run the scan one level deeper each time.

```shellscript wrap theme={null}
ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -ic -v -u http://TARGET_IP:PORT/FUZZ -e .html -recursion
```

Capping recursion depth and adding a rate limit keeps a recursive scan from spiraling out of control on a large site or a sensitive target.

```shellscript wrap theme={null}
ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -ic -u http://TARGET_IP:PORT/FUZZ -e .html -recursion -recursion-depth 2 -rate 500
```

POST body fuzzing works the same way, just put `FUZZ` in the data instead of the URL, handy for brute-forcing a parameter value behind a login or search form.

```shellscript wrap theme={null}
ffuf -u http://TARGET_IP:PORT/post.php -X POST -H "Content-Type: application/x-www-form-urlencoded" -d "y=FUZZ" -w /usr/share/seclists/Discovery/Web-Content/common.txt -mc 200 -v
```

> [!TIP]
>
> You can fuzz a specific extension directly in the wordlist entry using the `:FUZZ` keyword binding instead of appending `-e`, useful when you only care about one file type.
>
> ```shellscript wrap theme={null}
> ffuf -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-small.txt:FUZZ -u http://TARGET_IP:PORT/FUZZ.php
> ```

Subdomain brute-forcing swaps the `Host` header instead of the URL path, this works against a single IP even when DNS resolution for the subdomain doesn't exist yet.

```shellscript wrap theme={null}
ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -u http://TARGET_IP -H "Host: FUZZ.DOMAIN.TLD" -mc 200 -fl BASELINE_LINE_COUNT
```

> [!NOTE]
>
> `-fl` filters out responses with a specific line count. Run one request against a known-bad subdomain first to get the baseline "not found" page's line count, then filter it out so only genuine hits show up.

> [!WARNING]
>
> Without `-rate` a fuzzing run can hammer a target at full speed. On anything but a lab box, throttle it, both to avoid tripping WAF/IDS alerts and to avoid knocking over a fragile service.

***

## Gobuster

Gobuster covers the same ground as FFUF with a simpler flag set, split into separate subcommands (`dir`, `vhost`, `dns`) rather than one universal `FUZZ` keyword.

```shellscript wrap theme={null}
gobuster dir -u http://TARGET_IP/ -w /usr/share/dirb/wordlists/common.txt
```

Adding extensions and recursion in one pass, with `-b` excluding a known "not found" status code so it doesn't flood you with false positives.

```shellscript wrap theme={null}
gobuster dir -u http://TARGET_IP/ -w /usr/share/dirb/wordlists/common.txt -b 404 -x .php,.xml,.txt,.bak,.py -r
```

Virtual host discovery fuzzes the `Host` header the same way FFUF does, `--append-domain` saves you from having to write the full `FUZZ.domain.tld` pattern into the wordlist yourself.

```shellscript wrap theme={null}
gobuster vhost -u http://DOMAIN.TLD -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt --append-domain
```

The `dns` mode does straightforward DNS-based subdomain brute-forcing instead of hitting a web server directly.

```shellscript theme={null}
gobuster dns -d DOMAIN.TLD -w /usr/share/seclists/Discovery/DNS/namelist.txt
```

***

## DNSEnum

DNSenum pairs a standard DNS lookup (NS, MX, A records) with recursive subdomain brute-forcing in a single command, useful as a one-shot DNS recon pass before moving to a dedicated fuzzer.

```shellscript wrap theme={null}
dnsenum --enum DOMAIN.TLD -f /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt -r
```

***

## Dirb

Dirb predates FFUF and Gobuster and is slower, but it's still around on most distros by default and works fine for a quick pass without installing anything extra.

```shellscript theme={null}
dirb http://TARGET.TLD
```

Targeting backup and archive extensions specifically catches files developers tend to leave behind (`.bak`, `.old`, `.zip`, `.tar.gz`) that a default wordlist pass might miss.

```shellscript wrap theme={null}
dirb http://TARGET.TLD -w /usr/share/dirb/wordlists/big.txt -X .bak,.tar.gz,.zip
```

> **Other fuzzers worth knowing**
>
> **Feroxbuster** is a Rust-based recursive content discovery tool, faster than Gobuster at recursive scans and handles filtering/extensions similarly:
>
> ```shellscript theme={null}
> feroxbuster -u http://TARGET_IP -w /usr/share/seclists/Discovery/Web-Content/common.txt -x php,html,txt
> ```
>
> **Dirsearch** supports specifying the HTTP method directly, useful for APIs that don't respond the same way to GET as to other verbs:
>
> ```shellscript theme={null}
> dirsearch -u http://TARGET_IP -e php,html,js -m GET
> ```
>
> **Wfuzz** is another flexible fuzzer, similar in spirit to FFUF but with a slightly different flag syntax (`-w` for wordlist, `-z` for other payload types like ranges or files):
>
> ```shellscript theme={null}
> wfuzz -w /usr/share/seclists/Discovery/Web-Content/common.txt --hc 404 http://TARGET_IP/FUZZ
> ```

***

## Building a Custom Wordlist

> [!TIP]
>
> A generic wordlist misses target-specific terms (product names, internal project codenames, employee names). CeWL spiders a site and builds a wordlist from the words it actually contains, often turning up far better hits than SecLists alone.
>
> ```text theme={null}
> cewl http://TARGET.TLD -d 2 -m 5 -w custom-wordlist.txt
> ```

***

## Quick Reference Tools

> **[SecLists](https://github.com/danielmiessler/SecLists)**
>
> The standard wordlist collection, directories, subdomains, usernames, passwords, and more.

> **[FFUF](https://github.com/ffuf/ffuf)**
>
> Fast, flexible fuzzer covering directories, files, parameters, and vhosts.

> **[Gobuster](https://github.com/OJ/gobuster)**
>
> Directory, DNS, and vhost brute-forcing with a simpler flag set.

> **[Feroxbuster](https://github.com/epi052/feroxbuster)**
>
> Rust-based recursive content discovery, fast on deep directory trees.

> **[CeWL](https://github.com/digininja/CeWL)**
>
> Builds a target-specific wordlist by spidering the site's own content.

> [!WARNING]
>
> Fuzzing generates a large volume of requests fast. Only run this against targets you're explicitly authorized to test, and throttle (`-rate`, `-t`, `-p`) on anything shared or production-adjacent.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.