October 23, 2026
The Complete Bug Bounty Recon Methodology: From Subdomain Enumeration to Vulnerability Discovery |…
When I start testing a web application, I don’t immediately jump into vulnerability scanning. I think good reconnaissance is one of the…

By Samadhan shimple
9 min read
When I start testing a web application, I don't immediately jump into vulnerability scanning. I think good reconnaissance is one of the most important parts of bug bounty hunting.
Before testing for SQL injection, XSS, IDOR, or other vulnerabilities, I try to understand the target's attack surface. I want to know which subdomains exist, which services are running, what URLs are available, and where security weaknesses might be hiding.
In this article, I'll share my reconnaissance workflow using tools like Subfinder, crt.sh, Naabu, httpx, Katana, Gxss, Kxss, GF, Nuclei, and Subzy.
I use these tools as part of a structured workflow rather than running every scanner blindly. My goal is to find useful leads, validate them manually, and report genuine security issues with clear evidence.
1. Setting Up My Working Directory
I prefer to keep every engagement organized. When I collect hundreds or thousands of subdomains and URLs, a clean directory structure makes the results easier to manage.
I start by creating a directory for the target.
mkdir example
cd examplemkdir example
cd exampleFor larger assessments, I also separate the results into folders for subdomains, URLs, JavaScript files, scan output, and verified findings.
I think this small step saves a lot of time later. It also makes it easier to compare results and avoid repeating the same tests.
2. Subdomain Enumeration: Finding the Attack Surface
Subdomain enumeration is one of my first steps because organizations often operate multiple applications under the same root domain.
Some subdomains may host development environments, APIs, authentication systems, or older applications. These are worth reviewing when they fall within the authorized scope.
Using Subfinder
I use Subfinder to collect subdomains from supported passive sources.
subfinder -d example.com -all -recursive > subdomain1.txtsubfinder -d example.com -all -recursive > subdomain1.txtTo count the collected entries, I run:
cat subdomain1.txt | wc -lcat subdomain1.txt | wc -lThe number tells me how much data I have collected, but it doesn't tell me how many unique or active assets exist. I still need to clean and validate the results.
Using crt.sh
Certificate Transparency logs are another useful source for discovering hostnames that have appeared in TLS certificates.
For example, I can query crt.sh and extract the returned names with jq.
curl -s "https://crt.sh/?q=%.example.com&output=json" \
| jq -r '.[].name_value' \
| sed 's/\*\.//g' \
| sort -u > subdomain2.txtcurl -s "https://crt.sh/?q=%.example.com&output=json" \
| jq -r '.[].name_value' \
| sed 's/\*\.//g' \
| sort -u > subdomain2.txtThis command removes wildcard prefixes and duplicate entries. Some returned names may still be outdated, so I treat them as leads rather than confirmed assets.
Combining the Results
Next, I combine the output from both sources.
cat subdomain1.txt subdomain2.txt | sort -u > subdomains.txtcat subdomain1.txt subdomain2.txt | sort -u > subdomains.txtnow have a consolidated list that I can use in the next stage.
My takeaway: I don't rely on one enumeration tool. Combining different sources can reveal additional assets, but I always verify that each asset is in scope before testing it.
3. Port Scanning with Naabu
Finding a hostname is only part of reconnaissance. I also want to understand which network services are exposed on authorized targets.
Naabu helps identify open ports and can integrate with Nmap for additional service information.
For an approved test environment, I can use:
naabu -list subdomains.txt -c 50 \
-nmap-cli 'nmap -sV -sC' \
-o naabu-full.txtnaabu -list subdomains.txt -c 50 \
-nmap-cli 'nmap -sV -sC' \
-o naabu-full.txtThe output can help identify services that deserve further review.
For example, an exposed administrative service might need closer investigation. However, an open port alone does not prove that a vulnerability exists.
I also avoid aggressive scanning unless the program explicitly permits it. High concurrency and broad service detection can create unnecessary traffic or affect fragile systems.
4. Checking Which Subdomains Respond to HTTP
After enumeration, I use an HTTP probing tool to identify hosts that respond on common web ports.
cat subdomains.txt | httpx -ports 80,443,8080,8000,8888 \
-threads 50 > subdomains_alive.txtcat subdomains.txt | httpx -ports 80,443,8080,8000,8888 \
-threads 50 > subdomains_alive.txtIf your installation provides a command named httpx-toolkit, use the syntax supported by that version.
To count the resulting entries:
cat subdomains_alive.txt | wc -lcat subdomains_alive.txt | wc -lI use this output to build a list of web applications that I can inspect more closely.
A responding host isn't automatically vulnerable, and a non-responding host isn't necessarily irrelevant. DNS, firewalls, virtual hosting, and network restrictions can affect the results.
5. Discovering URLs with Katana
Once I have a list of responding web applications, I move to URL discovery.
Katana can crawl web applications and collect links, endpoints, and other URL references.
katana -list subdomains_alive.txt -d 3 \
-jc -o allurls.txtkatana -list subdomains_alive.txt -d 3 \
-jc -o allurls.txtExact flags can vary between Katana versions, so I check the installed tool's help output before using additional crawling options.
I review the collected URLs for parameters, API routes, JavaScript files, and potentially sensitive paths.
Searching for Potentially Sensitive Files
I use simple filtering to identify URLs that deserve manual review.
grep -Ei '\.(txt|log|cache|secret|db|backup|yml|yaml|json|gz|rar|zip|config)([?#]|$)' \
allurls.txt > possible_sensitive_files.txtgrep -Ei '\.(txt|log|cache|secret|db|backup|yml|yaml|json|gz|rar|zip|config)([?#]|$)' \
allurls.txt > possible_sensitive_files.txtI don't assume that every matching URL exposes confidential information. A JSON file might contain public configuration, while a backup file could contain sensitive data.
The important step is to verify whether the content is actually exposed and whether that exposure has a security impact.
Finding Parameterized URLs
I also extract URLs containing query parameters for further testing.
grep '=' allurls.txt | sort -u > parameterized_urls.txtgrep '=' allurls.txt | sort -u > parameterized_urls.txtI use this list to identify application functions that accept user-controlled input.
For example, parameters related to search, file selection, account settings, and redirects may be worth reviewing. Their names alone do not establish a vulnerability.
6. Reviewing Potential XSS and Other Input-Handling Issues
Cross-site scripting is another vulnerability class I investigate when the application processes user-controlled input.
Tools such as Gxss and Kxss can help identify interesting reflection behavior, depending on their versions and configuration.
I start by reviewing the relevant URLs and testing a small number of authorized cases. I then inspect how the application handles the input and whether it appears in an executable context.
I think manual validation is essential here. A reflected value is not necessarily XSS because modern frameworks, HTML encoding, and browser security controls can prevent execution.
I also avoid running payloads against real users or modifying data unnecessarily. The aim is to demonstrate a security weakness safely and with minimal impact.
7. Finding Open Redirect and File-Path Issues
I use GF patterns to filter URL collections for common vulnerability candidates.
For example, a pattern-based filter may help identify possible redirect parameters:
cat allurls.txt | gf redirect > redirect_candidates.txtcat allurls.txt | gf redirect > redirect_candidates.txtFor local file inclusion and path-traversal research, I may review a separate set of candidate URLs:
cat allurls.txt | gf lfi > file_path_candidates.txtcat allurls.txt | gf lfi > file_path_candidates.txtThe exact pattern names depend on the GF pattern collection installed on your system. A pattern match only identifies a possible testing candidate.
What I Look for During Validation
For redirects, I check whether an application improperly sends users to an untrusted destination and whether that behavior creates a meaningful security risk.
For file-path issues, I review whether a user-controlled value can escape its intended directory or expose files without proper authorization.
I keep testing within approved boundaries and avoid retrieving sensitive production data. A minimal, non-sensitive proof is preferable to accessing real secrets.
8. Reviewing JavaScript Files for Exposure Risks
JavaScript files can reveal useful information about an application's structure. They may contain API routes, feature flags, environment names, and references to third-party services.
I first identify JavaScript URLs:
grep -Ei '\.js([?#]|$)' allurls.txt | sort -u > js.txtgrep -Ei '\.js([?#]|$)' allurls.txt | sort -u > js.txtI then review the files for exposed credentials or other sensitive values using appropriate tools or manual inspection.
Tools such as SecretFinder can assist with this process, although installation and input requirements vary by version.
One important distinction: not every value called an API key is a secret. Some browser-side identifiers are intentionally public, while private credentials and privileged tokens can present serious risks.
If I discover a potentially valid credential, I don't use it to access accounts or services. I document the location and context, redact the value, and follow the program's reporting process.
9. Using Nuclei for Template-Based Detection
Nuclei is useful for checking known vulnerability patterns and exposures using templates.
I prefer starting with templates relevant to the technology and testing scope rather than running every available template against a target.
For example, a local template collection can be selected explicitly:
nuclei -l subdomains_alive.txt \
-t /path/to/approved-templates/ \
-o nuclei-results.txtnuclei -l subdomains_alive.txt \
-t /path/to/approved-templates/ \
-o nuclei-results.txtThe path above is a placeholder for a template directory that you have installed and reviewed.
I check the template descriptions, severity, and potential side effects before running them. Some templates make requests that may be unsuitable for production applications.
A scanner result is a lead, not a final report. I verify the affected endpoint, reproduce the behavior safely, and determine whether the result represents a real security issue.
10. Directory and File Discovery
Directory discovery can help identify forgotten routes, publicly accessible documentation, and misconfigured resources.
For an authorized staging application, a tool such as dirsearch can check a defined set of paths and extensions.
I keep the wordlist, extensions, concurrency, and request rate appropriate for the target. I also avoid large-scale discovery where the program prohibits brute-force testing.
When a route is discovered, I check whether it is expected to be public and whether access controls work correctly.
For example, a publicly accessible login page is usually normal. An administrative endpoint exposing sensitive records without authentication is a different situation.
What matters is the security impact, not simply the number of discovered directories.
11. Checking for Possible Subdomain Takeover
Subdomain takeover is worth investigating when a hostname points to an external service that may no longer be configured correctly.
Subzy can help identify potential takeover candidates.
subzy run --targets subdomains.txt --verify_sslsubzy run --targets subdomains.txt --verify_sslI treat its output as preliminary. A missing service, unusual error page, or dangling DNS record does not automatically mean the hostname is claimable.
I first verify the DNS configuration and provider-specific evidence. I do not attempt to claim or modify a hostname unless the owner and the applicable program explicitly authorize that action.
If a legitimate issue is confirmed, I document the DNS record, the provider response, and the potential impact without taking control of the resource.
12. Reviewing CORS Configuration
Cross-Origin Resource Sharing (CORS) controls whether browsers allow websites from other origins to read responses.
Misconfigured CORS can become a security issue when an untrusted origin is allowed to access sensitive responses, particularly when credentials are involved.
I use a CORS testing tool such as Corsy to identify suspicious configurations in an approved environment.
I focus on questions such as:
- Does the server reflect arbitrary origins?
- Does it allow credentials with an untrusted origin?
- Are sensitive endpoints affected?
- Can a browser actually read the protected response?
- Does the issue expose information that the requesting user should not be able to access?
A permissive CORS header alone does not establish a high-severity vulnerability. The response content, authentication requirements, browser behavior, and actual impact all matter.
I also avoid sending misleading identity headers or session cookies that could affect real users. I test with an account and environment I am authorized to use.
13. Reviewing Shortened URLs
URL-shortening services can hide the final destination of a link, which makes them relevant to phishing analysis and redirect investigations.
Tools such as ShortScan can help inspect supported shortened URLs.
I use this type of analysis to understand where a link leads and whether the destination creates a security concern. I don't assume that a shortened URL is malicious just because its destination is hidden.
When reviewing links, I avoid visiting suspicious destinations from a personal or production environment and never distribute harmful links to other people.
14. How I Turn Reconnaissance Results into Valid Findings
This is the part I consider most important.
Collecting thousands of subdomains, URLs, and scanner results can look impressive, but the real value comes from identifying a reproducible security issue.
My validation process is straightforward.
First, I confirm scope. I check that the hostname, application, and testing method are permitted by the program.
Second, I reproduce the behavior. I use a controlled test case and capture the relevant request and response.
Third, I establish impact. I determine what an attacker could actually achieve, rather than relying on a tool's severity label.
Fourth, I remove unnecessary risk. I avoid accessing other users' private data, changing production records, or causing service disruption.
Finally, I write a clear report. I include the affected endpoint, prerequisites, concise reproduction steps, evidence, realistic impact, and remediation guidance.
A good report should help the security team understand and reproduce the problem without having to guess what happened.
15. Common Mistakes I Try to Avoid
There are several mistakes that can waste time during bug bounty hunting.
- Trusting scanner output without verification: Automated tools can produce false positives.
- Ignoring program scope: A technically interesting host may not be authorized for testing.
- Treating every exposed file as a vulnerability: The content and access requirements determine the actual risk.
- Using aggressive settings by default: High concurrency can create unnecessary traffic and operational risk.
- Reporting impact that I haven't demonstrated: I keep conclusions aligned with the available evidence.
- Collecting data without a clear purpose: I focus on the minimum information needed to validate a finding.
I think a careful and repeatable workflow is more valuable than running every tool available.
Final Thoughts
My reconnaissance process starts with subdomain enumeration, moves through service discovery and URL collection, and ends with focused vulnerability validation.
Tools such as Subfinder, crt.sh, Naabu, httpx, Katana, GF, Nuclei, and Subzy each solve a different part of the problem. None of them can replace understanding how the target application works.
For me, successful bug bounty hunting is not about collecting the largest number of URLs or scanner alerts. It is about finding a real weakness, proving its impact safely, and communicating the result clearly.
AI assistance:_ I used an AI-powered grammar and spelling checker to review this article. The ideas, research, technical analysis, and final content are my own._
Have questions or want to share your own workflow? Drop a comment below or connect with me on :
🔗Linkdin: https://www.linkedin.com/company/sam-shield/
🔗Youtube: https://www.youtube.com/@sam_shield-w7l
🔗Medium: https://medium.com/@samadhanshimple