Recon Checklist
Recon is not “find as many subdomains as possible.” It is “find the assets that are most likely to be vulnerable fastest.” This is the order I run.
1. Scope mapping (5 min)
Before any tool runs, list:
- Apex domains in scope
- Wildcards (
*.target.com?) - Out-of-scope subdomains (often
support.target.com,status.target.com) - Out-of-scope severities (SPF/DMARC, self-XSS, etc.)
Putting this in scope.txt and out-of-scope.txt saves an hour of triage
arguing later.
2. Subdomain enumeration
Three sources, three rounds:
# Passive (CT logs, public DNS)
subfinder -d target.com -all -recursive -o subs.txt
amass enum -passive -d target.com >> subs.txt
curl -s "https://crt.sh/?q=%25.target.com&output=json" | jq -r '.[].name_value' >> subs.txt
# Resolve to filter the noise
sort -u subs.txt > subs-uniq.txt
dnsx -l subs-uniq.txt -resp -silent > subs-resolved.txt
# Active brute (only if scope allows)
puredns bruteforce wordlists/best-dns-wordlist.txt target.com >> subs-resolved.txt3. Port + service scan on live hosts
naabu -l alive.txt -top-ports 1000 -silent -o ports.txt
nmap -iL alive.txt -sV -sC -p$(cut -d: -f2 ports.txt | sort -u | paste -sd,) -oA scanFor non-standard ports specifically: that is where the dev/staging app the team forgot about lives.
4. HTTP probing + screenshotting
httpx -l subs-resolved.txt -title -tech-detect -status-code -o http.txt
gowitness scan file --file alive-urls.txt --threads 50I never start manual testing without looking at the screenshots first. Branding, login forms, and admin panels are visible in seconds. The page that looks “different” is almost always where the bug is.
5. Asset discovery on each host
Per app:
# Tech fingerprint
whatweb https://app.target.com
# JS endpoints (the goldmine)
gau https://app.target.com | grep -E "\.js$" | sort -u > js.txt
katana -u https://app.target.com -d 3 -jc -o crawled.txt
# Extract endpoints + secrets from JS
cat js.txt | xargs -I {} curl -s {} | grep -oE "(/[a-zA-Z0-9_/-]+)" | sort -u > endpoints.txt
trufflehog filesystem ./js --json90% of high-impact bug bounty findings I see come from parsing JavaScript for endpoints the developer thought were “internal.” If you skip JS recon, you ship duplicates.
6. Content discovery per app
ffuf -u https://app.target.com/FUZZ \
-w wordlists/raft-medium-words.txt \
-mc 200,204,301,302,401,403 \
-fc 404 -fs <stable-size-of-default-404> \
-o ffuf.json -of jsonThe -fs filter on the default-404 size is the difference between a useful
result list and 50k lines of noise.
7. The parts most people skip
These pay off more than they should:
- Source map files —
app.js.mapin production reveals the original source tree. Search for it on every JS endpoint. /.git/directory exposure —gitdumperit; you get the full history./.envfiles —ffufwith.env,.env.local,.env.production.- Backup files —
.bak,.old,.zip,.swpon common paths. - GraphQL introspection —
POST /graphqlwith{__schema{types{name}}}. If it answers, you have the whole API. - Login endpoints with rate limits per IP only — header-based bypasses
(
X-Forwarded-For,X-Real-IP,True-Client-IP). - Email signup with
+—me+admin@target.comsometimes lands in admin inboxes.
8. What goes into the report
For each finding I capture, in this order:
- Repro URL + minimal repro steps — 3 lines max
- Impact — what an attacker can actually do, not “could potentially lead to”
- Evidence — screenshot + curl repro
- Suggested fix — short, specific, no “use a WAF”
Programs pay faster when the triage engineer doesn’t have to write your bug for you.