subdomain-enum
When to Use
- Starting reconnaissance on a new target domain
- Need to discover all subdomains for attack surface mapping
- Expanding scope from a single root domain
- User provides a domain and asks about subdomains
- Building initial target list for vulnerability scanning
- Need to find hidden or forgotten subdomains
- Preparing for web application testing
- Asset discovery phase of bug bounty hunting
Quick Start
# Fast passive enumeration with subfinder
subfinder -d example.com -silent -o subdomains.txt
# Validate live subdomains with httpx
cat subdomains.txt | httpx -silent -o live_subdomains.txt
Step-by-Step Process
Phase 1: Fast Passive Enumeration (Subfinder)
Basic enumeration:
subfinder -d example.com -o subfinder_results.txtSilent mode for clean output:
subfinder -d example.com -silent -o subdomains.txtUse all sources (comprehensive):
subfinder -d example.com -all -o subdomains_all.txtJSON output:
subfinder -d example.com -silent -oJ -o subdomains.jsonMultiple domains from file:
subfinder -dL domains.txt -o all_subdomains.txtRecursive enumeration:
subfinder -d example.com -recursive -o recursive_subs.txt
Phase 2: Deep Enumeration (Amass)
Passive only:
amass enum -passive -d example.com -o amass_passive.txtActive enumeration:
amass enum -active -d example.com -o amass_active.txtWith brute forcing:
amass enum -brute -d example.com -o amass_brute.txtJSON output:
amass enum -d example.com -json amass_results.json
Phase 3: Validation (Httpx)
Basic probe:
cat subdomains.txt | httpx -silent -o live_hosts.txtWith status codes:
cat subdomains.txt | httpx -silent -sc -o live_with_status.txtFull information:
cat subdomains.txt | httpx -silent -sc -title -td -o detailed_hosts.txtJSON output:
cat subdomains.txt | httpx -silent -json -o httpx_results.jsonWith technology detection:
cat subdomains.txt | httpx -silent -td -json -o tech_results.json
Phase 4: Combine Results
cat subfinder_results.txt amass_passive.txt | sort -u > all_subdomains.txt
Examples
Example 1: Quick Bug Bounty Recon
Scenario: Fast subdomain discovery for a bug bounty target
subfinder -d hackerone.com -silent -o subs.txt
cat subs.txt | httpx -silent -sc -title
Output:
https://www.hackerone.com [200] [HackerOne | Bug Bounty Platform]
https://api.hackerone.com [401] [Unauthorized]
https://docs.hackerone.com [200] [HackerOne Platform Documentation]
https://support.hackerone.com [200] [HackerOne]
Example 2: Comprehensive Enumeration
Scenario: Thorough discovery with multiple tools
# Fast scan
subfinder -d target.com -all -o subfinder.txt
# Deep scan
amass enum -passive -d target.com -o amass.txt
# Combine
cat subfinder.txt amass.txt | sort -u > all_subs.txt
# Validate
cat all_subs.txt | httpx -silent -sc -title -td -json -o final.json
Example 3: Recursive Discovery
Scenario: Find sub-subdomains
subfinder -d example.com -recursive -o recursive.txt
Output:
api.example.com
dev.api.example.com
staging.api.example.com
internal.corp.example.com
Example 4: JSON Pipeline
Scenario: Structured output for processing
subfinder -d example.com -silent -oJ -o subs.json
cat subs.json | jq -r '.host' | httpx -silent -json -o httpx.json
cat httpx.json | jq -r 'select(.status_code == 200) | .url'
Example 5: Filter Interesting Targets
Scenario: Find high-value subdomains
subfinder -d target.com -silent -o subs.txt
grep -iE "(admin|dev|staging|test|api|internal|jenkins|jira)" subs.txt > interesting.txt
cat interesting.txt | httpx -silent -sc -title
Output:
https://admin.target.com [403] [Forbidden]
https://dev.target.com [200] [Development Environment]
https://jenkins.target.com [200] [Jenkins]
Example 6: Rate-Limited Scan
Scenario: Avoid detection
subfinder -d target.com -rl 5 -t 2 -o subs.txt
cat subs.txt | httpx -silent -rl 10 -t 25 -o live.txt
Example 7: Technology-Focused
Scenario: Find specific tech stacks
subfinder -d example.com -silent | httpx -silent -td -json -o tech.json
cat tech.json | jq 'select(.tech | contains(["WordPress"]))'
Error Handling
| Error | Cause | Resolution |
|---|---|---|
no results found |
No indexed subdomains | Try amass brute force |
context deadline exceeded |
Timeout | Increase -timeout |
rate limit exceeded |
Too many requests | Use -rl flag |
could not resolve host |
DNS failure | Check resolvers |
no sources configured |
Missing API keys | Configure provider-config.yaml |
connection refused |
Blocked | Use rate limiting |
too many open files |
Resource limit | Reduce -t threads |
Tool Reference
Subfinder Flags
| Flag | Description |
|---|---|
-d, -domain |
Target domain |
-dL, -list |
File with domains |
-all |
Use all sources |
-recursive |
Recursive enumeration |
-o, -output |
Output file |
-oJ, -json |
JSON output |
-silent |
Clean output |
-rl, -rate-limit |
Requests per second |
-t |
Concurrent threads |
-timeout |
Timeout seconds |
-r, -resolvers |
Custom resolvers |
-nW, -active |
Active subdomains only |
-config |
Config file path |
-pc, -provider-config |
API keys config |
Amass Flags
| Flag | Description |
|---|---|
-d |
Target domain |
-passive |
Passive only |
-active |
Include active |
-brute |
Enable brute force |
-o |
Output file |
-json |
JSON output |
-config |
Config file |
-w |
Wordlist for brute |
Httpx Flags
| Flag | Description |
|---|---|
-l, -list |
Input file |
-sc, -status-code |
Show status code |
-title |
Show page title |
-td, -tech-detect |
Detect technologies |
-ip |
Show IP address |
-cdn |
Show CDN detection |
-o, -output |
Output file |
-json |
JSON output |
-silent |
Clean output |
-mc, -match-code |
Match status codes |
-fc, -filter-code |
Filter status codes |
-t, -threads |
Thread count |
-rl, -rate-limit |
Requests per second |
Advanced Techniques
Wildcard Detection
# Check for wildcard
dig randomnonexistent123456.example.com +short
# Filter wildcards
subfinder -d example.com -nW -o filtered.txt
Certificate Transparency
# Query CT logs directly
curl -s "https://crt.sh/?q=%25.example.com&output=json" | jq -r '.[].name_value' | sort -u
ASN Discovery
# Find domains by ASN
amass intel -asn 12345 -o asn_domains.txt
Continuous Monitoring
# Baseline
subfinder -d example.com -silent -o baseline.txt
# Check for new
subfinder -d example.com -silent -o current.txt
diff baseline.txt current.txt > new_subs.txt
API Key Configuration
Subfinder (~/.config/subfinder/provider-config.yaml)
binaryedge:
- your_api_key
censys:
- your_api_id:your_api_secret
chaos:
- your_api_key
github:
- your_github_token
securitytrails:
- your_api_key
shodan:
- your_api_key
virustotal:
- your_api_key
Amass (~/.config/amass/config.yaml)
datasources:
SecurityTrails:
apikey: your_api_key
Shodan:
apikey: your_api_key
VirusTotal:
apikey: your_api_key
Best Practices
Recommended Workflow
- Start with subfinder - Fast, passive, low noise
- Run amass passive - Additional sources
- Run amass active - DNS brute forcing (if allowed)
- Combine and deduplicate - Merge all results
- Validate with httpx - Find live hosts
- Filter interesting - Focus on valuable targets
Performance Tips
- Use
-silentfor cleaner pipeline output - Set
-rlrate limits for large domains - Use
-jsonfor programmatic processing - Run subfinder first (faster), then amass (thorough)
- Increase timeouts for slow networks
- Use custom resolvers for better DNS resolution
Common Wordlists
| Wordlist | Size | Use Case |
|---|---|---|
subdomains-top1million-5000.txt |
5K | Quick |
subdomains-top1million-20000.txt |
20K | Standard |
dns-Jhaddix.txt |
2.2M | Comprehensive |
Output Interpretation
Subfinder JSON Output
{
"host": "api.example.com",
"input": "example.com",
"source": "alienvault"
}
| Field | Description |
|---|---|
host |
Discovered subdomain |
input |
Original target domain |
source |
Data source that found it |
Httpx JSON Output
{
"timestamp": "2024-01-15T10:30:00.000Z",
"url": "https://api.example.com",
"input": "api.example.com",
"status_code": 200,
"title": "API Documentation",
"webserver": "nginx/1.18.0",
"tech": ["nginx", "PHP"],
"content_length": 12345,
"host": "93.184.216.34",
"port": "443",
"scheme": "https"
}
| Field | Description |
|---|---|
url |
Full URL of the host |
status_code |
HTTP response code |
title |
HTML page title |
webserver |
Server header value |
tech |
Detected technologies |
content_length |
Response size |
host |
IP address |
Status Code Meanings
| Code | Meaning | Interest Level |
|---|---|---|
| 200 | OK | High - Active site |
| 301/302 | Redirect | Medium - Check destination |
| 401 | Unauthorized | High - Protected resource |
| 403 | Forbidden | High - Hidden content |
| 404 | Not Found | Low - May not exist |
| 500 | Server Error | Medium - Misconfigured |
| 502/503 | Gateway Error | Medium - Backend issues |
Integration Examples
Pipe to Nuclei
subfinder -d example.com -silent | httpx -silent | nuclei -t cves/
Pipe to Katana
subfinder -d example.com -silent | httpx -silent | katana -silent
Pipe to Naabu
subfinder -d example.com -silent | naabu -silent -top-ports 100
Full Recon Pipeline
# Complete subdomain enumeration pipeline
TARGET="example.com"
OUTDIR="recon/${TARGET}"
mkdir -p "$OUTDIR"
# Enumerate
subfinder -d "$TARGET" -all -o "$OUTDIR/subfinder.txt"
amass enum -passive -d "$TARGET" -o "$OUTDIR/amass.txt"
# Combine and dedupe
cat "$OUTDIR"/*.txt | sort -u > "$OUTDIR/all_subs.txt"
# Validate and fingerprint
cat "$OUTDIR/all_subs.txt" | httpx -silent -sc -title -td -json -o "$OUTDIR/live.json"
# Summary
echo "Found $(wc -l < $OUTDIR/all_subs.txt) subdomains"
echo "Live hosts: $(wc -l < $OUTDIR/live.json)"
References
- Subfinder | Amass | Httpx | SecLists DNS