DIRB
DIRB points a wordlist at a base URL, requests each word as a path, and reports which ones the server actually answers to. Reach for it early in web testing to answer one question: what paths exist here that nothing links to from the front page? It is small, predictable, and preinstalled on Kali, which keeps it useful as a first pass even though newer tools are faster.
Mental model: dirb URL [WORDLIST] [options]. URL first, wordlist second, flags last.
New to content discovery? Core concepts
- Base URL: the starting point; DIRB appends each word to it, so the trailing slash matters, for example
http://TARGET_IP/app/scans inside/app/ - Wordlist: the list of names to try; results live or die on it, for example
/usr/share/dirb/wordlists/common.txt - Status code: the whole signal, where
200is found,301/302is a redirect (often a real directory),403is forbidden but present, and404is hidden by default - Recursion: on by default, so a found directory gets scanned too;
-rturns it off - Extensions: append
.php,.txt,.bakto each word to find files, not just directories, with-X .php,.txt - Wildcard / soft 404: a server that answers
200to everything, making every word look found;-wpushes past the warning - No depth knob: DIRB has no recursion-depth limit and no thread flag, which is why deep scans explode and big lists are slow
When to reach for DIRB (and when not)
Reach for it for a quick classic content sweep on a simple lab or CTF box, a low-setup first pass before a heavier tool, an inventory of forgotten admin panels or backup files on your own servers, or when you want a tiny binary already on Kali with no runtime to install.
Reach for something else when the wordlist is large or you need speed (ffuf, feroxbuster), when you need to filter responses by size, words, or regex (ffuf), when you need real recursion-depth control (feroxbuster), or when the server returns soft 404s it will happily flood you with (ffuf with a size/word filter).
Install, update, verify#
sudo apt install -y dirb seclists # Debian / Ubuntu / Kali
sudo dnf install -y dirb # Fedora / RHEL (via EPEL)
sudo apt install --only-upgrade -y dirb seclists # update
dirb # no args: prints banner + version + usage
command -v dirb # confirm it is on PATH
ls /usr/share/dirb/wordlists/ # the bundled wordlists
DIRB has no --version flag; the version prints in that no-arg banner. It ships preinstalled on Kali and Parrot. Most of your “updating” is really keeping wordlists fresh (that is why seclists is installed alongside it), since list quality drives results far more than the binary version.
Flags you’ll actually use#
Skim these first; the cheat sheet below is these flags combined.
| Flag | Does | Flag | Does |
|---|---|---|---|
WORDLIST | Second positional: pick the list | -X .ext | Append extensions to each word |
-x file | Read extensions from a file | -o file | Save output to a file |
-r | Non-recursive (top level only) | -R | Interactive recursion (ask per dir) |
-z ms | Delay between requests | -S | Silent, hide tested words |
-w | Do not stop on the wildcard warning | -f | Fine-tune 404 detection |
-N code | Ignore responses with this code | -u u:p | HTTP basic auth |
-c cookie | Send a Cookie header | -H header | Send a custom header |
-p proxy | Route through a proxy | -a agent | Set the User-Agent |
-i | Case-insensitive search | -l | Print the Location header on hits |
-t | Do not force a trailing slash | -v | Also show NOT_FOUND pages |
Cheat sheet#
Every block starts simple and adds one flag at a time, so you can stop at the line that does the job.
# Build up a scan: stop at the line you need
dirb http://TARGET_IP/ # 1. default list, recursive
dirb http://TARGET_IP/ /usr/share/dirb/wordlists/common.txt # 2. + a real list
dirb http://TARGET_IP/ WORDLIST -r # 3. + top level only
dirb http://TARGET_IP/ WORDLIST -r -o scans/dirb.txt # 4. + save the results
# Files and extensions
dirb http://TARGET_IP/ WORDLIST -X .php,.txt,.bak # append these extensions
dirb http://TARGET_IP/ WORDLIST -x exts.txt # read extensions from a file
# Scope the scan
dirb http://TARGET_IP/app/ WORDLIST -r # inside one dir (mind the slash)
dirb http://DOMAIN/ WORDLIST # a vhost by name (must resolve)
dirb http://TARGET_IP/ WORDLIST -R # choose which dirs to recurse
# Auth and sessions
dirb http://TARGET_IP/admin/ WORDLIST -u USER:PASS # HTTP basic auth
dirb http://TARGET_IP/ WORDLIST -c "session=VALUE" # send a session cookie
dirb http://TARGET_IP/ WORDLIST -H "Authorization: Bearer TOKEN" # custom header
# Noise, load, stealth
dirb http://TARGET_IP/ WORDLIST -z 100 # 100ms between requests
dirb http://TARGET_IP/ WORDLIST -S # hide per-word progress
dirb http://TARGET_IP/ WORDLIST -a "Mozilla/5.0" # blend the User-Agent
# Wildcard / weird servers
dirb http://TARGET_IP/ WORDLIST -w # keep going past the warning
dirb http://TARGET_IP/ WORDLIST -f # fine-tune 404 detection
dirb http://TARGET_IP/ WORDLIST -N 403 # ignore all 403 responses
# Proxy and inspection
dirb http://TARGET_IP/ WORDLIST -p http://127.0.0.1:8080 # route through Burp/ZAP
# Pull found paths from a saved scan
grep '+ ' scans/dirb.txt # direct hits
grep 'DIRECTORY' scans/dirb.txt # discovered directories
Command breakdowns#
Each block below explains one situation, the exact command, and what to expect back.
Run a first-pass content scan#
dirb http://TARGET_IP/
Uses the built-in common.txt and recurses automatically. Prints the banner, the base URL, the wordlist, then each found path with its code and size. The fastest way to see if anything obvious is exposed.
Scan with a bigger, targeted wordlist#
dirb http://TARGET_IP/ /usr/share/dirb/wordlists/common.txt
The second positional argument replaces the default list. A better list is the single biggest lever on results, so when the default finds nothing, reach for a larger one from SecLists before concluding the box is empty.
Find files by appending extensions#
dirb http://TARGET_IP/ WORDLIST -X .php,.txt,.bak
-X appends each extension to every word, surfacing hits like index.php or config.bak. Keep the set small: every extension multiplies the request count on an already single-threaded tool.
Scan inside one directory only#
dirb http://TARGET_IP/app/ WORDLIST -r
The trailing slash scopes the scan to /app/, and -r stops it recursing back out. This is how you focus after a broad pass turns up an interesting directory.
Keep the scan shallow (no recursion)#
dirb http://TARGET_IP/ WORDLIST -r
-r disables the default recursion, so DIRB tests only the top level. Faster and far quieter on a deep site; re-run on a specific directory when you want depth.
Save results while you watch the scan#
dirb http://TARGET_IP/ WORDLIST -o scans/dirb.txt
-o writes a plain-text copy while the same output scrolls on screen. Always use it; re-running a noisy scan just because the terminal buffer rolled off is wasted time and extra log noise.
Scan a virtual host by name#
dirb http://DOMAIN/ WORDLIST -o scans/dirb-vhost.txt
DIRB scans whatever hostname you give it, so an /etc/hosts entry or DNS record that resolves DOMAIN lets you test a name-based vhost. Useful when one IP serves several sites.
Scan behind HTTP basic auth#
dirb http://TARGET_IP/admin/ WORDLIST -u USER:PASS
-u sends HTTP basic credentials with every request, so a 401-protected area you are authorized to reach gets scanned normally. Watch for 403 on individual paths even after auth succeeds.
Reuse a logged-in session cookie#
dirb http://TARGET_IP/ WORDLIST -c "session=COOKIEVALUE"
-c attaches a Cookie header, letting DIRB see the app as your logged-in session does. This is the way to discover post-login content that is invisible to an anonymous scan.
Route the scan through Burp or ZAP#
dirb http://TARGET_IP/ WORDLIST -p http://127.0.0.1:8080
-p sends every request through your proxy, so the full request/response history lands in Burp or ZAP for inspection and replay. Handy when you want to eyeball what a “found” line actually returned.
Slow the scan to cut noise and load#
dirb http://TARGET_IP/ WORDLIST -z 100
-z inserts a delay in milliseconds between requests. Eases a fragile lab box and softens the burst pattern that WAFs and rate limits key on. Pair with -S to keep the saved log clean.
Handle a server that answers 200 to everything#
dirb http://TARGET_IP/ WORDLIST -w
When DIRB warns about a wildcard (soft 404), -w tells it not to stop. Treat every hit as suspect: confirm a random nonsense path by hand, or switch to ffuf with a size filter.
Ignore a status code that floods the results#
dirb http://TARGET_IP/ WORDLIST -N 403
-N drops responses with a given code from the output. If a server blankets everything with 403, this clears the noise so the genuine 200 and 301 hits stand out.
Pull a clean list of found URLs#
grep '+ ' scans/dirb.txt | tee notes/found-paths.txt
DIRB marks direct hits with a leading +, so a one-line grep on the -o file extracts just the URLs. tee keeps a copy in your notes for the report.
Reading the output#
| You see | Meaning | Do next |
|---|---|---|
+ http://.../x (CODE:200|SIZE:n) | Direct hit, the path exists | Open it with curl or a browser |
==> DIRECTORY: .../x/ | A directory; DIRB will recurse in | Your best leads, scan inside |
(CODE:301) / (CODE:302) | Redirect, often a real dir or a login | Follow with curl -L |
(CODE:403) | Present but forbidden | Note it; try auth or another route |
| Clean run, nothing listed | 404 responses are hidden by default | Normal, not an error; try a bigger list |
WARNING: ... wildcard | Server answers 200 to anything | -w past it, verify by hand, or switch tools |
The signal is + (a hit), ==> DIRECTORY (a lead to recurse), and the CODE/SIZE on each line, which together tell you what kind of thing you found.
Troubleshooting#
| Problem | Cause | Fix |
|---|---|---|
command not found | Not installed / stale PATH | Reinstall dirb; open a fresh shell |
FATAL: Error connecting to the server | Wrong URL or host down | Verify with curl -I URL; check IP and port |
Every path reports 200 | Wildcard / soft 404 | Add -w, verify by hand, or switch to ffuf |
| No results at all | Weak wordlist or hidden 404s | Use a bigger list; confirm the URL with curl |
| Scan never finishes | Recursion exploded | Add -r, or scan one directory at a time |
| HTTPS errors on a lab box | Self-signed cert | Use http:// if offered, or proxy via Burp |
Auth area returns 401 | Missing credentials | Add -u USER:PASS or -c "session=VALUE" |
| Results differ from a tutorial | Different wordlist or version | Note the exact list; check the banner version |
Gotchas#
- The trailing slash decides the scope.
http://TARGET_IP/appscans the parent;http://TARGET_IP/app/scans inside/app/. DIRB forces an ending slash on URLs unless you pass-t. - Recursion is on by default and multiplies with extensions. A found directory plus
-X .php,.txt,.bakreruns every word times every extension inside it. On a deep site that explodes, so-ror scan one directory at a time. - A wildcard server turns every word into a fake hit. DIRB warns once; if you
-wpast it you get a wall of bogus200s. Test a random nonsense path first to confirm the server really 404s. - DIRB is single-threaded on purpose. There is no thread flag, so a large list is genuinely slow. That is the trade for “already installed and predictable”; when speed matters, that is your cue to leave.
- No
--versionand no JSON. The version only shows in the no-arg banner, and output is plain text, so machine-readable results meangrep/awkover the-ofile, not a--jsonswitch. -Xwants a leading dot and no spaces.-X .php,.bakworks;-X php, bakdoes not append what you think.
Pairs with#
nmap finds the open web ports first, so you know which URLs to feed DIRB. curl confirms each hit by hand and reads the headers and body DIRB only summarizes. When the list is large or the hits are noisy, ffuf filters responses by size, words, and regex, and feroxbuster does fast recursive discovery with real depth control; gobuster is the quick multi-threaded drop-in for the same job. DIRB still wins on simplicity and being already installed, which is enough for a small lab target before you move up.