Passive Subdomain Enumeration
Passive subdomain enumeration is a technique used to discover subdomains without directly interacting with the target’s infrastructure. Instead, it relies on publicly available data sources such as search engines, public DNS records, certificate transparency logs, and third-party services like VirusTotal
, SecurityTrails
, or Shodan
.
Content Security Policy (CSP) for subdomain enumeration
Content Security Policy (CSP) header allows administrators to specify which domains and subdomains are allowed to load content such as scripts, frame sources, image sources, etc.

The following curl
command can be used to extract domains from the CSP header:
curl -I -s <URL> | grep -iE 'content-security-policy|CSP' \
| tr " " "\n" | grep "\." | tr -d ";" \
| sed 's/\*\.//g' | sort -u
Favicon Hashes for subdomain enumeration
Subdomain enumeration via favicon hashes is a passive technique that identifies related domains by hashing a website's favicon (the small icon in the browser tab) and comparing it to hashes of other sites. Here's the process:
Fetch the favicon from
https://domain.com/favicon.ico
and hash it using MurmurHash3.Search for the hash in platforms like Shodan or Censys, which index the internet's favicon hashes.
Discover related subdomains: Sites sharing the same favicon hash often belong to the same organization. This can reveal hidden subdomains.
Let's use it with Shodan:
curl -s "<URL>/favicon.ico" | base64 | python3 -c 'import mmh3, sys;print(mmh3.hash(sys.stdin.buffer.read()))' \
| xargs -I{} shodan search http.favicon.hash:{} --fields hostnames \
| tr ";" "\n"
Subject Alternative Name (SAN) for subdomain enumeration
When a website uses an SSL/TLS certificate, it often includes a field called SAN
(Subject Alternative Name) that contains a list of all domains and subdomains for which the certificate is valid.
The following command initiates a connection to <DOMAIN>
using SSL/TLS to retrieve the certificate, then extracts and formats the subdomains from the SAN field for readability:
true | openssl s_client -connect <DOMAIN>:443 2>/dev/null \
| openssl x509 -noout -text | grep "DNS" | tr ',' '\n' | cut -d ":" -f2
Web Archives for subdomain enumeration
The following command fetches data from web archives and extracts the unique subdomains found:
echo $domain | gau --subs | unfurl -u domains | sort -u
Tools:
Subdomains from JavaScript files
curl -s $URL/file.js | grep -Po "((http|https):\/\/)?(([\w.-]*)\.([\w]*)\.([A-z]))\w+" \
| sort -u | grep $domain
Requires API Key.
python3 github-subdomains.py -t <TOKEN> -d $domain
RapidDNS
curl -s "https://rapiddns.io/subdomain/$domain?full=1" \
| grep -Eo '[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}' | sort -u
subfinder -d $domain -all -silent -no-color
assetfinder -subs-only $domain
python3 sublist3r.py -d $domain --no-color
amass enum -d $domain -passive -r resolvers.txt -silent
# Add this in .bashrc
crt(){
curl -s "https://crt.sh/?q=%25.$1" \
| grep -oE "[\.a-zA-Z0-9-]+\.$1" \
| sort -u
}
# Function example
crt $domain
Default scan will bruteforce, be careful.
# Check Alive Subdomains [Bruteforce False]
python3 oneforall.py --target example.com run --alive True [--brute=False]
python3 oneforall.py --targets ./examples.txt run --alive True --takeover True [--brute=False]
# Explore results - Only get subdomains
cat results.csv | awk -F',' '{print $5}' | tail -n +2
# Check all Subdomains + Takeover [Bruteforce False]
python3 oneforall.py --target example.com run --takeover True [--brute=False]
python3 oneforall.py --targets ./examples.txt run --takeover True --takeover True [--brute=False]
Documentation in english here.
Other usefull API Tools
Security Trails API -> https://api.securitytrails.com
Alien Vault OTX API -> https://otx.alienvault.com/api
URLScan -> https://urlscan.io
HackerTarget -> https://hackertarget.com
Pentest-Tools -> https://pentest-tools.com
DNSdumpster -> https://dnsdumpster.com
Last updated
Was this helpful?