Subdomain enumeration is where every serious offensive security workflow starts. The attack surface you can see is a fraction of what's actually exposed — forgotten staging environments, decommissioned APIs, and misconfigured dev subdomains rarely appear in a scope doc. This guide covers how to automate subdomain discovery, validate live hosts, and chain the output directly into vulnerability scanning pipelines.
Modern organizations run dozens to hundreds of subdomains — most of which the security team has only partial visibility into. A wildcard scope like *.target.com on a bug bounty program is an open invitation to map the full asset inventory. The highest-severity findings on most programs don't come from the main application — they come from forgotten assets at the edges of the subdomain space.
Subdomain recon feeds directly into every downstream workflow: Nuclei automation, FFUF endpoint discovery, SQLMap injection testing, and attack surface prioritization. Without a comprehensive and continuously updated subdomain list, every other stage of your autonomous penetration testing pipeline is operating on incomplete data.
dev., staging., test., uat. subdomains often run older software versions with weaker auth controls and no WAF coverage.
admin., portal., dashboard., manage. subdomains frequently expose internal tools to the public internet with default credentials.
Dangling CNAME records pointing to deprovisioned cloud services are claimable — a category that's consistently in scope and pays well.
api-v1., api-old., legacy. subdomains often run unpatched service versions that were "turned off" but never actually removed from DNS.
Manual subdomain enumeration — running one tool, checking the output, moving on — misses the majority of the actual subdomain space. Each tool uses different data sources: certificate transparency logs, DNS brute force, search engine indexing, ASN data, and third-party datasets. No single tool covers all of them.
Beyond coverage gaps, manual recon has no mechanism for tracking change over time. A subdomain added to scope three weeks after you ran your initial recon won't be in your list. Programs with active development cycles add new subdomains continuously — which means the attack surface you mapped on day one is stale by week two.
Subfinder alone misses subdomains that only appear in ASN data. Amass alone is slower than combining tools. Coverage requires multiple enumeration sources merged together.
Raw subdomain lists contain dead hosts, parking pages, and NXDOMAIN records. Feeding these into scanners wastes time and generates noise.
Running recon once and never again means new subdomains added after your initial sweep are never scanned — even if they're vulnerable on day one.
Manual recon output requires manual reformatting before feeding into Nuclei, FFUF, or other downstream tools — adding friction to every stage of the workflow.
The distinction between passive and active recon is operational, not academic. Passive recon leaves no footprint on the target — it queries third-party data sources that already hold indexed information about the target's infrastructure. Active recon sends packets directly to the target and will appear in server logs. On bug bounty programs, the wrong sequencing — running active brute force before checking scope — is the fastest way to get banned or reported.
Passive enumeration queries external databases that aggregate DNS and certificate data without ever touching the target directly. The three primary sources are certificate transparency logs (every TLS certificate ever issued is public), passive DNS datasets (historical DNS resolution records), and search engine indexes. Combined, they surface the majority of a target's subdomain footprint with zero detection risk.
# Certificate transparency logs + passive DNS (Subfinder)
subfinder -d target.com -silent -all -o passive-sf.txt
# crt.sh + VirusTotal + Facebook CT (Assetfinder)
assetfinder --subs-only target.com > passive-af.txt
# ASN data + CT logs + passive DNS (Amass passive mode)
amass enum -passive -d target.com -o passive-am.txt
# Merge all passive results
cat passive-sf.txt passive-af.txt passive-am.txt | sort -u > passive-all.txt
echo "[*] Passive total: $(wc -l < passive-all.txt) subdomains"
Passive enumeration is safe to run against any target at any time — including before you've confirmed program scope. It leaves no footprint, generates no server-side logs, and cannot be classified as unauthorized access. Always exhaust passive sources before escalating to active probing.
Active recon sends DNS queries or HTTP requests directly toward the target's infrastructure. It surfaces subdomains that don't exist in any public dataset — internal tooling prefixes, recently provisioned environments, and org-specific naming conventions that passive sources haven't indexed yet. Active recon should only run after confirming the program explicitly permits it and after passive enumeration is complete.
# DNS brute force with permutation wordlist (shuffledns)
shuffledns -d target.com -w /opt/homebrew/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -r /opt/homebrew/share/resolvers.txt -silent > active-brute.txt
# Active DNS enumeration with zone transfer attempt (Amass active)
amass enum -active -d target.com -o active-amass.txt
# DNS validation of combined passive + active results
cat passive-all.txt active-brute.txt active-amass.txt | sort -u | dnsx -silent > dns-validated.txt
echo "[*] DNS-validated: $(wc -l < dns-validated.txt) subdomains"
Queries third-party CT logs, passive DNS, and search indexes. Safe against any target, any time. Use Subfinder, Assetfinder, Amass passive.
Sends DNS queries directly to target resolvers. Surfaces subdomains absent from public datasets. Use shuffledns, Amass active, massdns.
Run dnsx on merged passive + active output before httpx. Eliminates NXDOMAIN noise and surfaces dangling CNAMEs in one pass.
Feed DNS-validated subdomains into httpx to confirm live web services. This is what feeds Nuclei, FFUF, and every downstream scanner.
Each tool in a subdomain recon pipeline serves a distinct purpose. Understanding where each fits prevents redundant execution and ensures maximum coverage without unnecessary noise. Use the Recon Workflow Generator to auto-build pipelines from this toolset.
| Tool | Mode | Primary Source | Best For |
|---|---|---|---|
| subfinder | Passive | CT logs, DNS datasets, APIs | Fast passive enumeration; best first-pass tool for any target |
| amass | Both | CT logs, ASN data, DNS brute force | Comprehensive enumeration; use passive mode first, active for deep coverage |
| assetfinder | Passive | crt.sh, Facebook, VirusTotal | Lightweight second-pass to catch subdomains Subfinder misses |
| dnsx | Active | DNS resolution | Validate DNS records, detect dangling CNAMEs for takeover detection |
| httpx | Active | HTTP/HTTPS probing | Filter live web hosts from validated DNS list; tech detection |
| shuffledns | Active | DNS brute force | Permutation-based subdomain brute forcing using custom wordlists |
Always run passive tools (Subfinder, Amass passive, Assetfinder) before active probing (dnsx, httpx, Shuffledns). Passive enumeration leaves zero footprint. Active probing generates server-side logs and may trigger alerts on monitored targets — only escalate after confirming program scope allows active testing.
These are the actual command sequences used in production recon pipelines. Each workflow builds on the previous — start with the one-liner for quick sweeps, use the full pipeline for programs you're actively hunting on a schedule.
The minimum viable recon pipeline. Discovers subdomains passively and immediately filters to live web hosts. Output is ready for Nuclei or FFUF without any intermediate steps.
subfinder -d target.com -silent | \
httpx -silent -threads 50 | \
tee live-hosts.txt
Running three passive tools and merging output maximizes subdomain coverage. Each tool hits different data sources — combining them catches subdomains that a single tool would miss. Feed the merged list into dnsx before httpx for more accurate DNS validation.
# Run three passive tools in parallel
subfinder -d target.com -silent -o subs-sf.txt &
assetfinder --subs-only target.com > subs-af.txt &
amass enum -passive -d target.com -o subs-am.txt &
wait
# Merge and deduplicate
cat subs-sf.txt subs-af.txt subs-am.txt \
| sort -u \
> subs-all.txt
echo "[*] Total unique subdomains: $(wc -l < subs-all.txt)"
After merging passive output, run dnsx to validate which subdomains have active DNS records and flag dangling CNAMEs. A CNAME pointing to an unclaimed S3 bucket, GitHub Pages, or Heroku app is a potential subdomain takeover — one of the most reliable high-severity finding categories in bug bounty.
# Resolve all subdomains, output with CNAME records
dnsx \
-l subs-all.txt \
-silent \
-resp \
-a -cname \
-o dns-resolved.txt
# Extract subdomains with active DNS (no NXDOMAIN)
dnsx \
-l subs-all.txt \
-silent \
> dns-valid.txt
# Check for dangling CNAMEs (potential takeover)
dnsx \
-l subs-all.txt \
-cname \
-silent \
| grep -E 'amazonaws|github\.io|heroku|azurewebsites|shopify|fastly' \
> potential-takeovers.txt
echo "[*] Potential takeovers: $(wc -l < potential-takeovers.txt)"
The complete subdomain recon automation pipeline — from root domain to vulnerability findings in one script. This is what you schedule as a cron job on a VPS for programs you actively hunt. Integrates directly with the Nuclei automation workflow and feeds output ready for FFUF endpoint discovery.
#!/usr/bin/env bash
# PhantomRed — Full Subdomain Recon Automation Pipeline
# Usage: ./recon-full-pipeline.sh target.com
# Requires: subfinder, amass, assetfinder, dnsx, httpx, nuclei
TARGET="$1"
OUT="./recon/${TARGET}/$(date +%Y%m%d)"
mkdir -p "$OUT"
# STAGE 1 — Passive subdomain enumeration (parallel)
echo "[1/5] Passive enumeration"
/opt/homebrew/bin/subfinder -d "$TARGET" -silent -o "$OUT/sf.txt" &
/opt/homebrew/bin/assetfinder --subs-only "$TARGET" > "$OUT/af.txt" &
/opt/homebrew/bin/amass enum -passive -d "$TARGET" -o "$OUT/am.txt" &
wait
cat "$OUT/sf.txt" "$OUT/af.txt" "$OUT/am.txt" \
| sort -u \
> "$OUT/subs-all.txt"
echo " Unique subdomains: $(wc -l < $OUT/subs-all.txt)"
# STAGE 2 — DNS validation
echo "[2/5] DNS validation"
/opt/homebrew/bin/dnsx \
-l "$OUT/subs-all.txt" \
-silent \
-o "$OUT/dns-valid.txt"
echo " DNS-valid: $(wc -l < $OUT/dns-valid.txt)"
# STAGE 3 — Live HTTP/HTTPS probing
echo "[3/5] Live host probing"
/opt/homebrew/bin/httpx \
-l "$OUT/dns-valid.txt" \
-silent \
-threads 50 \
-timeout 10 \
-tech-detect \
-status-code \
-o "$OUT/live-hosts.txt"
echo " Live hosts: $(wc -l < $OUT/live-hosts.txt)"
# STAGE 4 — Nuclei scan on live hosts
echo "[4/5] Nuclei scan"
/opt/homebrew/bin/nuclei \
-l "$OUT/live-hosts.txt" \
-t exposures/,cves/,misconfiguration/,takeovers/ \
-severity medium,high,critical \
-rl 50 \
-bulk-size 25 \
-timeout 10 \
-silent \
-json \
-o "$OUT/nuclei-results.json"
# STAGE 5 — Triage summary
echo "[5/5] Triage"
/opt/homebrew/bin/jq \
-r '[.info.severity, .host, .info.name] | @tsv' \
"$OUT/nuclei-results.json" \
| sort -k1 \
> "$OUT/triage.txt"
echo "[✓] Done. Results: $OUT/triage.txt"
echo " Critical : $(grep -c 'critical' $OUT/triage.txt 2>/dev/null || echo 0)"
echo " High : $(grep -c '^high' $OUT/triage.txt 2>/dev/null || echo 0)"
echo " Medium : $(grep -c '^medium' $OUT/triage.txt 2>/dev/null || echo 0)"
After passive enumeration, use shuffledns to brute-force common subdomain permutations. This catches subdomains that don't appear in any public dataset — internal tooling prefixes, numbered environments, and org-specific naming conventions.
# Brute force using a common subdomain wordlist
# SecLists: Discovery/DNS/subdomains-top1million-5000.txt
shuffledns \
-d target.com \
-w /opt/homebrew/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt \
-r /opt/homebrew/share/resolvers.txt \
-silent \
> subs-brute.txt
# Merge with passive results
cat subs-all.txt subs-brute.txt | sort -u > subs-complete.txt
Add this pipeline to cron for programs you actively hunt: 0 6 * * * /path/to/recon-full-pipeline.sh target.com — runs at 6am daily. New subdomains added to the program's scope are automatically swept within 24 hours. Diff the triage output against previous runs to surface only net-new findings.
PhantomRed runs the full subdomain recon pipeline server-side. Submit a target domain, configure your scope, and the platform executes Subfinder, Amass, dnsx, and httpx in sequence — then feeds the validated live-host list into Nuclei automation workflows automatically. No tool installation, no cron management, no manual pipeline wiring.
The critical difference from running scripts yourself: PhantomRed persists your subdomain inventory across sessions and runs delta detection on every re-scan. New subdomains discovered on a re-run are flagged as net-new assets and immediately swept for vulnerabilities. You get notified on new findings — not on the same 400 known subdomains you already mapped last week. See the full reconnaissance automation for bug bounty overview for context on how recon fits into the wider workflow.
Subfinder + Amass passive run in parallel against your target. Results are merged and deduplicated automatically.
subfinder + amassdnsx resolves all subdomains and flags dangling CNAMEs pointing to claimable external services.
dnsxhttpx filters DNS-valid subdomains down to live web services and fingerprints technologies for targeted scanning.
httpxLive hosts are automatically fed into Nuclei with template categories matched to detected technologies.
nucleiNew subdomains and findings are compared against previous runs. Only net-new assets and vulnerabilities surface in your dashboard.
phantomred engineMost recon automation failures aren't tool failures — they're sequencing and configuration failures. These are the five patterns that consistently produce bad output, wasted scan cycles, or worse, missed vulnerabilities on targets you thought you'd fully covered.
Feeding Subfinder output directly into Nuclei or FFUF without a dnsx or httpx filter means executing templates against NXDOMAIN records, expired domains, and parked pages. These generate connection errors that look like scan results, inflate output files, and mask real findings in noise. Fix: always pipe through dnsx -silent then httpx -silent before any active scanning stage.
Each tool queries different data sources. Subfinder alone misses subdomains only in ASN records. Amass alone is slower than running tools in parallel. Assetfinder catches subdomains from Facebook CT logs that neither Subfinder nor Amass index. Running a single tool consistently leaves 20–40% of the actual subdomain space undiscovered. Fix: always merge output from at least Subfinder + Amass passive before downstream stages.
DNS brute force (shuffledns, Amass active) generates significant query volume against target resolvers and will appear in logs. Running it before passive enumeration — which costs nothing and surfaces the majority of known subdomains — wastes both time and detection budget. Fix: exhaust passive sources first; only escalate to active brute force for targets where passive coverage is thin.
Re-running the same recon pipeline without diffing against previous output forces you to re-triage your entire known subdomain inventory every time. On programs with 200+ subdomains, this means reviewing the same assets repeatedly instead of focusing on what changed. Fix: store each run's output with a date-stamped directory and use comm -13 <(sort prev.txt) <(sort current.txt) to extract net-new subdomains only.
Most hunters validate subdomains for HTTP response only and move on. CNAME records pointing to deprovisioned cloud services (S3, GitHub Pages, Heroku, Azure) are claimable — and subdomain takeover is consistently one of the highest-paying finding categories on most programs. Fix: add dnsx -cname to your pipeline and grep for known claimable provider patterns before running your HTTP scan.
subfinder -d target.com -silent | httpx -silent -o live.txt. For full coverage, run all three passive tools and merge before DNS validation.
Run the full subdomain discovery and validation pipeline autonomously. PhantomRed handles enumeration, DNS validation, live probing, and vulnerability scanning — and notifies you only on net-new findings.