Web Content Discovery
Content discovery finds endpoints the app doesn't link to: admin panels, backups, APIs, debug paths, and unlinked apps. Complement it with web crawling to map the visible attack surface first. Run it after tech fingerprinting so you know which extensions and wordlists match the stack. Discovery output feeds into parameter crawling and exposed git directory checks.
Check robots.txt and sitemap.xml
Before running a wordlist scan, check what the application exposes willingly. robots.txt often reveals admin paths, API directories, and staging endpoints that the site owner tried to hide from search engines. sitemap.xml maps out the full URL structure:
User-agent: * Disallow: /admin/ Disallow: /api/internal/ Disallow: /backup/ Allow: /
Explain command
| -sk | Silent mode, skip TLS certificate verification. |
Every Disallow entry is a path worth testing directly. Combine the results with wordlist output to avoid duplicating effort.
ffuf Baseline
ffuf is the default choice. Fast, flexible filtering, and handles custom 404s cleanly:
Explain command
| -w /usr/share/seclists/Discovery/Web-Content/common.txt | Wordlist file path used for fuzzing input. |
| -u http://$TARGET_IP:$PORT/FUZZ | Target URL with FUZZ keyword marking the injection point. |
| $TARGET_IP:$PORT | Variable placeholders for the target host IP and port. |
| -mc 200,204,301,302,307,401,403 | Match only responses with these specific HTTP status codes. |
301/302 to a new path is real content. 401/403 is still interesting: it's a valid endpoint behind auth. If everything returns a hit, you're seeing a custom 404 and need size filtering.
Handle Custom 404s with Size Filtering
Measure the error response size, then exclude it:
4242
Explain command
| -s | Silent mode; suppresses progress meter and error messages. |
| -k | Allow insecure TLS connections, skipping certificate verification. |
| http://$TARGET_IP:$PORT/thisshouldnotexist | Target URL with variable host/port to a non-existent path. |
Explain command
| -w /usr/share/seclists/Discovery/Web-Content/common.txt | Wordlist file path used for fuzzing input. |
| -u http://$TARGET_IP:$PORT/FUZZ | Target URL with FUZZ keyword as the injection point. |
| $TARGET_IP:$PORT | Variable placeholders for the target host IP and port. |
| -mc 200,204,301,302,307,401,403 | Match only responses with these HTTP status codes. |
| -fs 4242 | Filter out responses with a body size of 4242 bytes. |
Replace 4242 with the actual size. For apps returning varying sizes on 404, filter by word count with -fw instead.
Stack-Matched Extensions
Match extensions to what fingerprinting revealed. Wrong extensions waste significant time on large wordlists:
Explain command
| -w /usr/share/seclists/Discovery/Web-Content/common.txt | Wordlist file used for fuzzing input. |
| -u http://$TARGET_IP:$PORT/FUZZ | Target URL with FUZZ keyword marking the injection point. |
| $TARGET_IP:$PORT | Variable placeholders for the target host IP and port. |
| -e .php,.php5,.phtml,.html,.txt,.bak,.old,.zip | File extensions to append to each wordlist entry. |
| -mc 200,204,301,302,307,401,403 | Match only responses with these HTTP status codes. |
Explain command
| -w /usr/share/seclists/Discovery/Web-Content/common.txt | Wordlist file to use for fuzzing input. |
| -u http://$TARGET_IP:$PORT/FUZZ | Target URL with FUZZ keyword as the injection point. |
| $TARGET_IP:$PORT | Variable placeholders for target host IP and port. |
| -e .asp,.aspx,.ashx,.asmx,.config,.txt,.bak | Append these extensions to each wordlist entry during fuzzing. |
| -mc 200,204,301,302,307,401,403 | Match only responses with these HTTP status codes. |
Explain command
| -w /usr/share/seclists/Discovery/Web-Content/common.txt | Wordlist file to use for fuzzing input. |
| -u http://$TARGET_IP:$PORT/FUZZ | Target URL with FUZZ as the injection point placeholder. |
| $TARGET_IP:$PORT | Variable placeholders for the target host IP and port. |
| -e .jsp,.jspx,.do,.action,.txt,.xml | Append these extensions to each wordlist entry during fuzzing. |
| -mc 200,204,301,302,307,401,403 | Match only responses with these specific HTTP status codes. |
Recursive Discovery
ffuf handles recursion but feroxbuster is faster and more reliable for deep trees:
Explain command
| -w /usr/share/seclists/Discovery/Web-Content/common.txt | Wordlist file to use for fuzzing input. |
| -u http://$TARGET_IP:$PORT/FUZZ | Target URL with FUZZ keyword marking the injection point. |
| $TARGET_IP:$PORT | Placeholder for target host IP address and port number. |
| -mc 200,204,301,302,307,401,403 | Match only responses with these HTTP status codes. |
| -recursion | Enable recursive fuzzing on discovered directories. |
| -recursion-depth 2 | Limit recursive fuzzing to a maximum depth of 2 levels. |
Explain command
| -u http://$TARGET_IP:$PORT/ | Target URL to perform directory/file brute-forcing against. |
| -w /usr/share/seclists/Discovery/Web-Content/common.txt | Wordlist file used for brute-forcing paths and filenames. |
| -x php,html,txt,js,json | File extensions to append to each wordlist entry during fuzzing. |
| -t 30 | Number of concurrent threads to use for scanning. |
| -k | Disable TLS certificate validation for HTTPS targets. |
Explain command
| -u | Target URL to begin directory/file brute-forcing against. |
| http://$TARGET_IP:$PORT/ | Base URL with variable host and port placeholders. |
| -w | Wordlist file path to use for brute-forcing. |
| /usr/share/seclists/Discovery/Web-Content/common.txt | Common web content wordlist from SecLists collection. |
| -x | File extensions to append to each wordlist entry during fuzzing. |
| php,html,txt,js,json | Extensions to test: PHP, HTML, plain text, JavaScript, and JSON. |
| -C | HTTP status codes to filter out (exclude) from results. |
| 404,302 | Suppresses responses with Not Found and Redirect status codes. |
| -o | Output file path to save scan results. |
| ferox_results.txt | File where discovered results will be written. |
Authenticated Discovery
Run a second pass authenticated to find endpoints only visible after login:
Explain command
| -w /usr/share/seclists/Discovery/Web-Content/common.txt | Wordlist file to use for fuzzing input. |
| -u http://$TARGET_IP:$PORT/FUZZ | Target URL with FUZZ keyword marking the injection point. |
| $TARGET_IP:$PORT | Placeholder for the target host IP and port number. |
| -H "Cookie: session=REPLACE_ME" | Adds a custom Cookie header with a session token to each request. |
| -mc 200,204,301,302,307,401,403 | Match only responses with these specific HTTP status codes. |
Explain command
| -w /usr/share/seclists/Discovery/Web-Content/common.txt | Wordlist file to use for fuzzing. |
| -u http://$USER:$PASSWORD@$TARGET_IP:$PORT/FUZZ | Target URL with HTTP Basic Auth credentials embedded in the URL. |
| -mc 200,204,301,302,307,401,403 | Match HTTP response codes to include in results. |
Larger Wordlists for Deeper Web Content Discovery
When common.txt misses things, upgrade the wordlist. raft and directory-list are heavier but surface more results:
Explain command
| -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories.txt | Wordlist file used for fuzzing directory names. |
| -u http://$TARGET_IP:$PORT/FUZZ | Target URL with FUZZ keyword marking the injection point. |
| $TARGET_IP:$PORT | Variable placeholders for the target host IP and port. |
| -mc 200,204,301,302,307,401,403 | Match only responses with these specific HTTP status codes. |
Explain command
| -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt | Wordlist file to use for fuzzing input. |
| -u http://$TARGET_IP:$PORT/FUZZ | Target URL with FUZZ keyword marking the injection point. |
| $TARGET_IP:$PORT | Placeholder for the target host IP and port number. |
| -mc 200,204,301,302,307,401,403 | Match only responses with these HTTP status codes. |
| -t 100 | Number of concurrent threads to use for requests. |
Wordlist selection by use case:
common.txt: fast first pass, covers standard paths and filenamesraft-medium-directories.txt: broader directory names from real-world crawlsdirectory-list-2.3-medium.txt: large general-purpose list, slow but thoroughbig.txt: exhaustive, use when medium lists miss and you have timequickhits.txt: targeted checks for config files, backups, and admin paths
Tech-Specific Wordlists
After fingerprinting the stack, swap in a matching wordlist from SecLists. These surface paths that generic lists miss:
Discovery/Web-Content/CGIs.txt: CGI scripts on Apache, common in legacy appsDiscovery/Web-Content/IIS.fuzz.txt: IIS-specific paths, config files, and handler mappingsDiscovery/Web-Content/apache.txt: Apache-specific directories and config pathsDiscovery/Web-Content/nginx.txt: nginx status pages, config paths, and common misconfigsDiscovery/Web-Content/tomcat.txt: Tomcat manager, host-manager, and deployment pathsDiscovery/Web-Content/AdobeCQ-AEM.txt: Adobe Experience Manager nodes and servlets
Run the generic list first, then the tech-specific one. Overlap is minimal.
Gobuster and dirsearch as Alternatives
Notice
dirb is deprecated. Wfuzz is still useful for multi-payload fuzzing (e.g., fuzzing path and parameter simultaneously with multiple FUZZ keywords) and built-in encoder chains. For standard single-wordlist directory brute-forcing, ffuf and feroxbuster are faster.
Explain command
| dir | Use directory/file brute-forcing mode. |
| -u | Target URL to enumerate. |
| http://$TARGET_IP:$PORT/ | Base URL with variable host and port placeholders. |
| -w | Wordlist file path to use for brute-forcing. |
| /usr/share/seclists/Discovery/Web-Content/common.txt | Common web content wordlist from SecLists. |
| -x | File extensions to append to each wordlist entry. |
| php,html,txt,js,json | Extensions to try: php, html, txt, js, and json. |
| --random-agent | Use a random User-Agent string per request. |
| -t | Number of concurrent threads to use. |
| 50 | Thread count value: 50 parallel requests. |
| -o | Write output results to a specified file. |
| gobuster.txt | Output file where results will be saved. |
Explain command
| -u http://$TARGET_IP:$PORT/ | Target URL to perform directory brute-forcing against. |
| -w /usr/share/seclists/Discovery/Web-Content/common.txt | Wordlist file used for directory and file enumeration. |
| -e php,html,txt,js,json | File extensions to append to each wordlist entry during scan. |
| -i 200,204,301,302,307,401,403 | Only include responses matching these HTTP status codes. |
| -t 50 | Number of concurrent threads to use during the scan. |
| -o dirsearch.txt | Write scan output/results to the specified file. |
References
-
Matchers, filters, recursion, and output formats
-
Recursive forced browsing and filtering options
-
dir mode usage and flags
-
Web content wordlists including raft, common, and directory-list