Subdomain Enumeration Tools
Subdomain Enumeration Tools
Comprehensive collection of subdomain enumeration tools and techniques for reconnaissance and web application security testing.
Subfinder
Basic Subdomain Enumeration
# Basic subdomain enumeration
subfinder -d TARGET_DOMAIN
# With multiple domains
subfinder -d TARGET_DOMAIN1,TARGET_DOMAIN2,TARGET_DOMAIN3
# With output file
subfinder -d TARGET_DOMAIN -o results.txt
# With JSON output
subfinder -d TARGET_DOMAIN -o results.json -json
# With verbose output
subfinder -d TARGET_DOMAIN -v
# With silent output
subfinder -d TARGET_DOMAIN -silent
# With threads
subfinder -d TARGET_DOMAIN -t 50
# With timeout
subfinder -d TARGET_DOMAIN -timeout 10
# With retries
subfinder -d TARGET_DOMAIN -retries 3
Advanced Subfinder Options
# With specific sources
subfinder -d TARGET_DOMAIN -sources shodan,crtsh,passivetotal
# With all sources
subfinder -d TARGET_DOMAIN -all
# With exclude sources
subfinder -d TARGET_DOMAIN -exclude-sources shodan,crtsh
# With config file
subfinder -d TARGET_DOMAIN -config config.yaml
# With proxy
subfinder -d TARGET_DOMAIN -proxy http://127.0.0.1:8080
# With rate limit
subfinder -d TARGET_DOMAIN -rate-limit 100
# With wildcard detection
subfinder -d TARGET_DOMAIN -wildcard
# With recursive enumeration
subfinder -d TARGET_DOMAIN -recursive
Amass
Basic Subdomain Enumeration
# Basic subdomain enumeration
amass enum -d TARGET_DOMAIN
# With multiple domains
amass enum -d TARGET_DOMAIN1,TARGET_DOMAIN2
# With output file
amass enum -d TARGET_DOMAIN -o results.txt
# With JSON output
amass enum -d TARGET_DOMAIN -json results.json
# With verbose output
amass enum -d TARGET_DOMAIN -v
# With silent output
amass enum -d TARGET_DOMAIN -silent
# With threads
amass enum -d TARGET_DOMAIN -t 50
# With timeout
amass enum -d TARGET_DOMAIN -timeout 10
Advanced Amass Options
# With specific sources
amass enum -d TARGET_DOMAIN -sources shodan,crtsh,passivetotal
# With all sources
amass enum -d TARGET_DOMAIN -all
# With exclude sources
amass enum -d TARGET_DOMAIN -exclude-sources shodan,crtsh
# With config file
amass enum -d TARGET_DOMAIN -config config.yaml
# With proxy
amass enum -d TARGET_DOMAIN -proxy http://127.0.0.1:8080
# With rate limit
amass enum -d TARGET_DOMAIN -rate-limit 100
# With wildcard detection
amass enum -d TARGET_DOMAIN -wildcard
# With recursive enumeration
amass enum -d TARGET_DOMAIN -recursive
# With brute force
amass enum -d TARGET_DOMAIN -brute
# With wordlist
amass enum -d TARGET_DOMAIN -w wordlist.txt
Assetfinder
Basic Subdomain Enumeration
# Basic subdomain enumeration
assetfinder TARGET_DOMAIN
# With multiple domains
assetfinder TARGET_DOMAIN1 TARGET_DOMAIN2 TARGET_DOMAIN3
# With output file
assetfinder TARGET_DOMAIN > results.txt
# With subs-only
assetfinder --subs-only TARGET_DOMAIN
# With alive check
assetfinder --alive TARGET_DOMAIN
# With verbose output
assetfinder -v TARGET_DOMAIN
Sublist3r
Basic Subdomain Enumeration
# Basic subdomain enumeration
sublist3r -d TARGET_DOMAIN
# With multiple domains
sublist3r -d TARGET_DOMAIN1,TARGET_DOMAIN2
# With output file
sublist3r -d TARGET_DOMAIN -o results.txt
# With verbose output
sublist3r -d TARGET_DOMAIN -v
# With threads
sublist3r -d TARGET_DOMAIN -t 50
# With timeout
sublist3r -d TARGET_DOMAIN -t 10
# With specific engines
sublist3r -d TARGET_DOMAIN -e google,yahoo,bing
# With all engines
sublist3r -d TARGET_DOMAIN -e all
# With exclude engines
sublist3r -d TARGET_DOMAIN -e google,yahoo -x bing,duckduckgo
DNSrecon
Basic DNS Enumeration
# Basic DNS enumeration
dnsrecon -d TARGET_DOMAIN
# With multiple domains
dnsrecon -d TARGET_DOMAIN1,TARGET_DOMAIN2
# With output file
dnsrecon -d TARGET_DOMAIN -o results.txt
# With JSON output
dnsrecon -d TARGET_DOMAIN -j results.json
# With verbose output
dnsrecon -d TARGET_DOMAIN -v
# With threads
dnsrecon -d TARGET_DOMAIN -t 50
# With timeout
dnsrecon -d TARGET_DOMAIN -t 10
# With specific record types
dnsrecon -d TARGET_DOMAIN -t A,AAAA,CNAME,MX,NS,SOA,TXT
# With all record types
dnsrecon -d TARGET_DOMAIN -t all
# With brute force
dnsrecon -d TARGET_DOMAIN -b
# With wordlist
dnsrecon -d TARGET_DOMAIN -w wordlist.txt
Fierce
Basic Subdomain Enumeration
# Basic subdomain enumeration
fierce -dns TARGET_DOMAIN
# With multiple domains
fierce -dns TARGET_DOMAIN1,TARGET_DOMAIN2
# With output file
fierce -dns TARGET_DOMAIN -file results.txt
# With verbose output
fierce -dns TARGET_DOMAIN -verbose
# With threads
fierce -dns TARGET_DOMAIN -threads 50
# With timeout
fierce -dns TARGET_DOMAIN -timeout 10
# With wordlist
fierce -dns TARGET_DOMAIN -wordlist wordlist.txt
# With range
fierce -dns TARGET_DOMAIN -range 192.168.1.0/24
# With delay
fierce -dns TARGET_DOMAIN -delay 1
DNSenum
Basic DNS Enumeration
# Basic DNS enumeration
dnsenum TARGET_DOMAIN
# With multiple domains
dnsenum TARGET_DOMAIN1 TARGET_DOMAIN2
# With output file
dnsenum TARGET_DOMAIN -o results.txt
# With verbose output
dnsenum TARGET_DOMAIN -v
# With threads
dnsenum TARGET_DOMAIN -t 50
# With timeout
dnsenum TARGET_DOMAIN -t 10
# With wordlist
dnsenum TARGET_DOMAIN -w wordlist.txt
# With range
dnsenum TARGET_DOMAIN -r 192.168.1.0/24
# With delay
dnsenum TARGET_DOMAIN -d 1
Custom Scripts
Python Subdomain Enumeration
import requests
import threading
import queue
import time
import dns.resolver
def subdomain_enumeration(domain, wordlist, threads=10, delay=0):
def worker():
while True:
try:
subdomain = wordlist.get()
if subdomain is None:
break
full_domain = f"{subdomain}.{domain}"
# DNS resolution
try:
dns.resolver.resolve(full_domain, 'A')
print(f"[DNS] {full_domain}")
except:
pass
# HTTP check
try:
response = requests.get(f"http://{full_domain}", timeout=5)
print(f"[HTTP] {full_domain} - {response.status_code}")
except:
pass
# HTTPS check
try:
response = requests.get(f"https://{full_domain}", timeout=5)
print(f"[HTTPS] {full_domain} - {response.status_code}")
except:
pass
time.sleep(delay)
except Exception as e:
pass
finally:
wordlist.task_done()
# Start threads
for i in range(threads):
t = threading.Thread(target=worker)
t.daemon = True
t.start()
# Add subdomains to queue
with open(wordlist_file, 'r') as f:
for line in f:
wordlist.put(line.strip())
# Wait for completion
wordlist.join()
# Usage
domain = "TARGET_DOMAIN"
wordlist_file = "/usr/share/wordlists/subdomains.txt"
wordlist = queue.Queue()
subdomain_enumeration(domain, wordlist, threads=20, delay=0.1)
Bash Subdomain Enumeration
#!/bin/bash
DOMAIN="TARGET_DOMAIN"
WORDLIST="/usr/share/wordlists/subdomains.txt"
THREADS=10
# Function to check subdomain
check_subdomain() {
local subdomain=$1
local full_domain="${subdomain}.${DOMAIN}"
# DNS resolution
if nslookup "$full_domain" > /dev/null 2>&1; then
echo "[DNS] $full_domain"
fi
# HTTP check
if curl -s -o /dev/null -w "%{http_code}" "http://$full_domain" | grep -q "200\|301\|302\|403\|401"; then
echo "[HTTP] $full_domain"
fi
# HTTPS check
if curl -s -o /dev/null -w "%{http_code}" "https://$full_domain" | grep -q "200\|301\|302\|403\|401"; then
echo "[HTTPS] $full_domain"
fi
}
# Export function for parallel
export -f check_subdomain
export DOMAIN
# Run parallel subdomain check
cat "$WORDLIST" | parallel -j "$THREADS" check_subdomain {}
Wordlists
Common Subdomain Wordlists
# SecLists subdomain wordlists
/usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-5000.txt
/usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-110000.txt
/usr/share/wordlists/SecLists/Discovery/DNS/dns-Jhaddix.txt
# Custom subdomain wordlists
/usr/share/wordlists/custom/subdomains.txt
/usr/share/wordlists/custom/api-subdomains.txt
/usr/share/wordlists/custom/admin-subdomains.txt
# Generate custom wordlists
echo "www,mail,ftp,admin,api,dev,test,staging,prod" | tr ',' '\n' > custom_subdomains.txt
Creating Custom Wordlists
# Extract subdomains from certificate transparency logs
curl -s "https://crt.sh/?q=%.TARGET_DOMAIN&output=json" | jq -r '.[].name_value' | sort -u > crt_subdomains.txt
# Extract subdomains from DNS records
dig @8.8.8.8 TARGET_DOMAIN ANY | grep -oP 'IN\s+\w+\s+\K[^\s]+' | sort -u > dns_subdomains.txt
# Combine multiple wordlists
cat wordlist1.txt wordlist2.txt wordlist3.txt | sort -u > combined_wordlist.txt
# Remove empty lines and duplicates
grep -v '^$' wordlist.txt | sort -u > clean_wordlist.txt
API-based Enumeration
Shodan API
# Using Shodan CLI
shodan domain TARGET_DOMAIN
# Using Shodan API
curl -s "https://api.shodan.io/dns/domain/TARGET_DOMAIN?key=YOUR_API_KEY" | jq -r '.data[].subdomain' | sort -u
Censys API
# Using Censys API
curl -s "https://censys.io/api/v1/search/certificates" \
-H "Authorization: Basic YOUR_API_KEY" \
-d '{"query": "TARGET_DOMAIN", "fields": ["parsed.names"]}' | jq -r '.result.hits[].parsed.names[]' | sort -u
VirusTotal API
# Using VirusTotal API
curl -s "https://www.virustotal.com/vtapi/v2/domain/report" \
-d "apikey=YOUR_API_KEY" \
-d "domain=TARGET_DOMAIN" | jq -r '.subdomains[]' | sort -u
Passive vs Active Enumeration
Passive Enumeration
# Using only passive sources
subfinder -d TARGET_DOMAIN -sources crtsh,passivetotal,shodan
# Using only passive DNS
dnsrecon -d TARGET_DOMAIN -t A,AAAA,CNAME,MX,NS,SOA,TXT
# Using only certificate transparency
curl -s "https://crt.sh/?q=%.TARGET_DOMAIN&output=json" | jq -r '.[].name_value' | sort -u
Active Enumeration
# Using brute force
amass enum -d TARGET_DOMAIN -brute
# Using wordlist
subfinder -d TARGET_DOMAIN -w wordlist.txt
# Using recursive enumeration
subfinder -d TARGET_DOMAIN -recursive
Best Practices
Rate Limiting
# Add delay between requests
subfinder -d TARGET_DOMAIN -rate-limit 100
# Use fewer threads
subfinder -d TARGET_DOMAIN -t 10
# Use proxy rotation
subfinder -d TARGET_DOMAIN -proxy http://proxy1:8080
Stealth Mode
# Use random user agents
subfinder -d TARGET_DOMAIN -a "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
# Use realistic delays
subfinder -d TARGET_DOMAIN -rate-limit 50
# Use smaller wordlists
subfinder -d TARGET_DOMAIN -w /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-5000.txt
Output Analysis
# Save results to file
subfinder -d TARGET_DOMAIN -o results.txt
# Filter by status code
grep "200" results.txt
grep "403" results.txt
grep "301\|302" results.txt
# Sort by response size
sort -k3 -n results.txt
Troubleshooting
Common Issues
# Connection timeout
subfinder -d TARGET_DOMAIN -t 5
# Too many requests
subfinder -d TARGET_DOMAIN -rate-limit 50
# Invalid SSL certificate
subfinder -d TARGET_DOMAIN -k
# Authentication required
subfinder -d TARGET_DOMAIN -u admin -p password
Performance Optimization
# Use appropriate thread count
subfinder -d TARGET_DOMAIN -t 20
# Use smaller wordlists for initial scan
subfinder -d TARGET_DOMAIN -w /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-5000.txt
# Use specific sources
subfinder -d TARGET_DOMAIN -sources crtsh,passivetotal
Legal and Ethical Considerations
- Always obtain proper authorization before testing
- Respect rate limits and server resources
- Use appropriate wordlists for the target
- Document findings properly
- Follow responsible disclosure practices