The best Subdomain enumeration techniques guide
Subdomain enumeration is a fundamental technique in cybersecurity, focused on uncovering all the subdomains associated with a primary domain. This method is critical for security professionals, hackers, and corporate IT teams alike, as it reveals a comprehensive landscape of a company's web presence. By mapping out all subdomains, individuals can pinpoint potential vulnerabilities, overlooked areas, and hidden services that could be exploited or need protection.
The process involves using specialized tools and strategies to scan the vast expanse of the internet and systematically identify subdomains. This could uncover anything from development environments to external services, offering a clearer view of an organization's digital footprint. Performing subdomain enumeration is akin to charting a map of unknown territories, enabling a more informed approach to cybersecurity efforts.
Different types of subdomain enumeration.
1. Passive Enumeration
Passive enumeration involves collecting subdomain information without directly interacting with the target domain's servers. This method is discreet and reduces the risk of detection since it generally involves gathering data from third-party sources rather than the target system itself. Tools like VirusTotal, SecurityTrails, or search engines like Google can be utilized for passive enumeration. Given the increasing concerns over cybersecurity and privacy, this technique is preferred for initial reconnaissance, allowing testers to gather valuable information without raising alarms.
If you are a bug bounty hunter or a tester, you use the script below to passively enumerate subdomains.
-
Subfinder: Can be installed from Subfinder's GitHub page.
-
**dig**
: Usually pre-installed on Unix/Linux systems. -
Amass: Installation instructions are available on Amass's GitHub page.
-
Sublist3r: Can be cloned and installed from Sublist3r's GitHub page.
-
Knockpy: Available on Knockpy's GitHub page, this tool requires Python for its execution.
# Enhanced Passive Enumeration Bash Script
# Target domain
read -p "Enter the target domain: " targetDomain
echo "Performing enhanced passive enumeration on $targetDomain"
# Using dig for DNS information gathering
echo "Gathering DNS records..."
dig @$targetDomain ANY +noall +answer
# ENUMERATION SECTION
# Subdomain enumeration with Subfinder
echo "Enumerating subdomains with Subfinder..."
subfinder -d $targetDomain -o subfinder\_subs.txt
echo "Subfinder results saved to subfinder\_subs.txt"
# Subdomain enumeration with Amass
echo "Enumerating subdomains with Amass..."
amass enum -d $targetDomain -o amass\_subs.txt
echo "Amass results saved to amass\_subs.txt"
# Subdomain enumeration with Sublist3r
echo "Enumerating subdomains with Sublist3r..."
sublist3r -d $targetDomain -o sublist3r\_subs.txt
echo "Sublist3r results saved to sublist3r\_subs.txt"
# Subdomain enumeration with Knockpy
echo "Enumerating subdomains with Knockpy..."
knockpy $targetDomain -o knockpy\_subs.csv
echo "Knockpy results saved to knockpy\_subs.csv"
# WAYBACK MACHINE HISTORICAL DATA
echo "Searching Wayback Machine for historical data..."
wget -O wayback\-data.txt "https://web.archive.org/cdx/search/cdx?url=\*$targetDomain\*&output=text"
echo "Historical data saved to wayback-data.txt"
# Display completion message
echo "Enhanced passive enumeration completed successfully."
2. Active Enumeration
Active enumeration methods involve direct interaction with the target's domain system. This could include sending DNS or HTTP requests to the target’s servers. Tools like Sublist3r, DNSMap, or Amass perform DNS queries to find subdomains actively. While this method can yield more comprehensive results compared to passive techniques, it also increases the risk of detection. In an era where organizations are constantly on the alert for cyber threats, using active enumeration requires careful timing and justification.
Let’s walk through a simple bash script that utilizes Nmap
, a powerful tool for network discovery and security auditing. This script aims to discover live hosts and scan for open ports on a target domain.
Note: This script is for educational purposes; always seek permission before testing on live environments.
# Enhanced active enumeration script using naabu and nmap.
if \[ "$#" -ne 1 \]; then
echo "Usage: $0 <target\_domain\_or\_IP>"
exit 1
fi
TARGET=$1
OUTPUT\_DIR\=$(mktemp -d -t enum-XXXXXXXXXX) # Creating a temporary directory for scan outputs.
echo "Output files will be saved in $OUTPUT\_DIR"
# Stage 1: Fast Port Scanning with naabu.
echo "\[\*\] Performing fast port scan with naabu on $TARGET..."
naabu -host $TARGET -o $OUTPUT\_DIR/naabu\_output.txt
# Extracting open ports for further scanning.
OPEN\_PORTS\=$(cat $OUTPUT\_DIR/naabu\_output.txt | cut -d ":" -f2 | tr '\\n' ',' | sed 's/,$//')
if \[ -z "$OPEN\_PORTS" \]; then
echo "No open ports found. Exiting."
exit 1
fi
echo "\[\*\] Found open ports: $OPEN\_PORTS"
# Stage 2: Detailed Scan with nmap.
echo "\[\*\] Performing detailed scan with nmap on discovered ports..."
nmap -p $OPEN\_PORTS -sV $TARGET -oN $OUTPUT\_DIR/nmap\_detailed\_scan.txt
echo "Enumeration completed. Check $OUTPUT\_DIR for detailed scan results."
# Cleanup
# Optionally, remove the temporary directory if you don't need the scan results.
# rm -rf $OUTPUT\_DIR
3. Brute-Force Enumeration
This technique involves systematically guessing subdomain names and checking if they exist. Utilizing wordlists containing common subdomain names, tools like fierce or Knock can automate the process. As this method generates a high volume of DNS queries, it's easily detectable and might not always be efficient against well-configured rate limiting and monitoring defences. However, with the growing sophistication of bot detection and blocking mechanisms, brute-force enumeration tools have also evolved, now incorporating delay tactics and user-agent spoofing to mimic legitimate traffic.
#!/bin/bash
# Script for brute\-force subdomain enumeration using fierce
# Make sure the user provides a domain name to scan
if \[ "$#" -ne 1 \]; then
echo "Usage: $0 <domain>"
exit 1
fi
DOMAIN\=$1
# Specify a wordlist. Adjust the path according to your setup.
# You can find numerous wordlists in tools like SecLists (https://github.com/danielmiessler/SecLists)
WORDLIST\="/path/to/your/subdomains/wordlist.txt"
echo "Starting brute-force subdomain enumeration for $DOMAIN using fierce"
echo "This might take a while..."
# Run fierce with delay options to mimic legitimate traffic, reducing the chance of blocking.
# Remove '--delay' option or adjust it as per rate\-limiting policies of the target domain if needed.
fierce --domain $DOMAIN --wordlist $WORDLIST --delay 3
echo "Enumeration completed."
checkout for more payloads [here](https://github.com/danielmiessler/SecLists/tree/master/Discovery/DNS).
save the bash script as `_name.sh_` and then give executable rights `_chmod +x name.sh_`
4. DNS Zone Transfer
DNS Zone Transfer (AXFR) is a type of active enumeration where the tester attempts to request a copy of the entire DNS zone for a domain. This is only possible if the DNS servers are misconfigured to allow such transfers to unauthorized users. Although this vulnerability is less common now due to better default configurations and awareness, it remains a critical check during a VAPT exercise. In today's environment, where misconfigurations are a leading cause of data breaches, verifying DNS zone transfer settings is integral.
#!/bin/bash
\# Comprehensive DNS Zone Transfer check using multiple tools.
if \[ "$#" -ne 2 \]; then
echo "Usage: $0 <Domain> <DNS Server>"
exit 1
fi
DOMAIN\=$1
DNSSERVER\=$2
TIMESTAMP\=$(date +%Y%m%d\-%H%M%S)
OUTPUT\_DIR\="DNS\_Zone\_Transfer\_$TIMESTAMP"
mkdir -p $OUTPUT\_DIR
\# Function to perform DNS Zone Transfer using dig
function check\_dig {
echo "1. Using dig for DNS Zone Transfer..."
dig @$DNSSERVER $DOMAIN AXFR > "$OUTPUT\_DIR/dig\_$DOMAIN.txt"
echo "Done. Output saved to $OUTPUT\_DIR/dig\_$DOMAIN.txt"
echo "---------------------------------------------------------------------"
}
\# Function to perform DNS Zone Transfer using host
function check\_host {
echo "2. Using host for DNS Zone Transfer..."
host -l $DOMAIN $DNSSERVER > "$OUTPUT\_DIR/host\_$DOMAIN.txt"
echo "Done. Output saved to $OUTPUT\_DIR/host\_$DOMAIN.txt"
echo "---------------------------------------------------------------------"
}
\# Function to perform DNS Zone Transfer using nslookup
function check\_nslookup {
echo "3. Using nslookup for DNS Zone Transfer..."
echo -e "server $DNSSERVER\\nls -d $DOMAIN" | nslookup > "$OUTPUT\_DIR/nslookup\_$DOMAIN.txt"
echo "Done. Output saved to $OUTPUT\_DIR/nslookup\_$DOMAIN.txt"
echo "---------------------------------------------------------------------"
}
# Running all checks
echo "DNS Zone Transfer checks for $DOMAIN using server $DNSSERVER..."
echo "====================================================================="
check\_dig
check\_host
check\_nslookup
echo "All checks complete. Review the outputs in the $OUTPUT\_DIR directory."
The script first ensures you’ve provided a domain and its DNS server, then sets up a timestamped output directory to avoid overwriting past results. It performs DNS Zone Transfer checks using three separate functions for dig, host, and nslookup, with each function’s output saved in a unique text file within the designated directory for easy identification and analysis.
- Prepare the Script:
-
Save the script to a file, for example as
dns_zone_transfer_check.sh
. -
Make the script executable by running
chmod +x dns_zone_transfer_check.sh
in your terminal.
2. Execute the Script:
-
Run the script with the domain and DNS server as arguments:
-
./dns_zone_transfer_check.sh example.com ns.example.com
-
Replace
example.com
andns.example.com
with your target domain and its authoritative DNS server, respectively.
5. Certificate Transparency Logs
Certificate Transparency logs are an increasingly popular source for subdomain enumeration. These publicly available logs are meant to prevent SSL certificates from being issued for a domain without the domain owner’s knowledge. Tools that search these logs, such as crt.sh, can reveal subdomains that have had SSL certificates issued, offering an updated view of an organization's internet-facing assets. With the rising enforcement of HTTPS and the proliferation of SSL certificates, leveraging CT logs for enumeration aligns with current security best practices.
#!/bin/bash
\# Check if domain is provided
if \[ -z "$1" \]; then
echo "Usage: $0 <domain>"
exit 1
fi
DOMAIN\=$1
# Define user\-agent to use with curl for querying crt.sh
USER\_AGENT\="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3"
\# Query crt.sh for subdomains & clean up the output
echo "Enumerating subdomains for $DOMAIN from crt.sh..."
curl -s -A "$USER\_AGENT" "https://crt.sh/?q=%.$DOMAIN&output=json" | jq -r '.\[\].name\_value' | sed 's/\\\*\\.//g' | sort -u
echo "Enumeration complete."
Explanation:
-
Checking Input: The script starts by checking if you’ve provided a domain as an argument. If not, it prompts you to use the correct usage format and exits.
-
Setting Variables: The
DOMAIN
variable holds the domain to query. TheUSER_AGENT
string is set to identify the script as a legitimate browser session while making requests. This helps in case certain services have checks to block non-browser user agents. -
Enumeration Process:
-
It utilizes
curl
to query crt.sh's JSON output for certificates related to the domain. The-s
flag silencescurl
's progress output, and-A
specifies the user agent. -
The output is filtered through
jq
(a lightweight and flexible command-line JSON processor) to extract the domain names from each certificate entry. -
The
sed
command strips any wildcard entries (e.g.,*.example.com
), as these are not specific subdomains. -
The
sort -u
command sorts the output and removes any duplicate entries.
Requirements:
-
You must have
jq
installed on your system to process JSON output (sudo apt-get install jq
on Debian/Ubuntu orbrew install jq
on MacOS). -
Ensure
curl
is installed (usually pre-installed on most UNIX systems).
Usage: To use the script, save it to a file, make it executable with chmod +x scriptname.sh
, and run it with a domain as an argument:
./scriptname.sh example.com
-
Dorking from google
Google Dorking leverages advanced search operators in Google to unearth information that might not be readily available through regular searches. It's like using special keywords and commands to unlock hidden corners of the internet. This technique can be used for good, like security professionals like finding subdomains and also to find hidden files and directories.
#!/bin/bash
# Prompt user for target domain
read -p "Enter target domain (e.g., example.com): " target
# Remove temporary files (if any) silently
rm -rf subdomain\_scan\_tmp1.txt subdomain\_scan\_tmp.txt &> /dev/null
# Extract the first part of the domain (without TLD)
sfe\=$(echo "$target" | cut -d "." -f 1)
# Set a loop duration (adjust as needed)
runtime\="40 seconds"
endtime\=$(date -ud "$runtime" +%s)
# Loop for the specified duration
while \[\[ $(date -u +%s) -le $endtime \]\]; do
# Start with "www" subdomain
echo -n "+-www" > subdomain\_scan\_tmp.txt
# Loop through common subdomain prefixes (add more as needed)
for prefix in mail ftp blog shop; do
potential\_subdomain\="$prefix.$target"
# Check if the subdomain resolves to an IP (basic validation)
if host -t A "$potential\_subdomain" &> /dev/null; then
echo "+-$potential\_subdomain" >> subdomain\_scan\_tmp.txt
fi
done
# Use Google search for additional discovery (limited accuracy)
# Be aware of Google's terms of service
search\_url\="https://www.google.com/search?q=site:$target"
user\_agent\="Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
# Download search results silently and filter for potential subdomains
potential\_subdomains\=$(curl -s -A "$user\_agent" "$search\_url" | grep -Eo "(http|https)://\[^/\]+" | grep -i "$target")
# Extract subdomain names and remove duplicates
for subdomain in $potential\_subdomains; do
subdomain\_name\=$(echo "$subdomain" | cut -d '/' -f 3 | cut -d '.' -f 1)
if \[\[ "$subdomain\_name" != "$sfe" \]\]; then
echo "+-$subdomain\_name" >> subdomain\_scan\_tmp.txt
fi
done
# Sort and remove duplicates from the temporary file
cat subdomain\_scan\_tmp.txt | tr '+-' '\\n' | sort -u | sed 's/^/+-/' | tr -d '\\n' > subdomain\_scan\_tmp1.txt
# Move temporary file content to the main temporary file
mv subdomain\_scan\_tmp1.txt subdomain\_scan\_tmp.txt
done
\# Print discovered subdomains (remove leading "+" sign)
cat subdomain\_scan\_tmp.txt | tr '+-' '\\n' | sed 's/^+//'
\# Remove temporary files again
rm -rf subdomain\_scan\_tmp1.txt subdomain\_scan\_tmp.txt
This code scans a domain for potential subdomains. It checks common prefixes (mail, ftp) and uses Google search (be mindful of terms!). It avoids duplicate entries and prints the findings.
To run it:
-
Save the code as a file (e.g., scan.sh).
-
Open a terminal and navigate to the file location (use
cd
). -
Make the script executable with
chmod +x scan.sh
. -
Run it with
./scan.sh
. Enter your target domain (e.g., example.com) when prompted.
The Final Work!
This script incorporates functions for each enumeration technique: passive, active, brute-force, DNS zone transfer, and Google Dorking. It accepts the target domain and wordlist as inputs and then sequentially executes each enumeration technique.
Ensure that you have separate scripts for each technique (e.g., certificate_transparency_logs.sh
, active_enumeration.sh
, brute_force_enumeration.sh
, dns_zone_transfer_check.sh
, and google_dorking.sh
), and they are executable and located in the same directory as the main script.
To use the script:
-
Save the main script and each individual enumeration script in separate files.
-
Make all the scripts executable (e.g.,
chmod +x script_name.sh
). -
Run the main script (
./main_script.sh
). -
Follow the prompts to enter the target domain and wordlist path.
#!/bin/bash
# Function for passive enumeration
passive\_enum() {
targetDomain\=$1
echo "Performing passive enumeration for $targetDomain..."
# Passive enumeration using certificate transparency logs
./certificate\_transparency\_logs.sh "$targetDomain"
echo "Passive enumeration completed."
}
# Function for active enumeration
active\_enum() {
target\=$1
echo "Performing active enumeration for $target..."
# Active enumeration using naabu and nmap
./active\_enumeration.sh "$target"
echo "Active enumeration completed."
}
# Function for brute\-force enumeration
brute\_force\_enum() {
target\=$1
wordlist\=$2
echo "Performing brute-force enumeration for $target using $wordlist..."
# Brute\-force enumeration using fierce
./brute\_force\_enumeration.sh "$target" "$wordlist"
echo "Brute-force enumeration completed."
}
# Function for DNS zone transfer
dns\_zone\_transfer() {
domain\=$1
dnsServer\=$2
echo "Performing DNS zone transfer check for $domain using DNS server $dnsServer..."
# DNS zone transfer check
./dns\_zone\_transfer\_check.sh "$domain" "$dnsServer"
echo "DNS zone transfer check completed."
}
# Function for Google Dorking
google\_dorking() {
target\=$1
echo "Performing Google Dorking for $target..."
# Google Dorking
./google\_dorking.sh "$target"
echo "Google Dorking completed."
}
# Main function
main() {
# Accept target domain and wordlist as inputs
read -p "Enter the target domain: " targetDomain
read -p "Enter the wordlist path: " wordlist
# Perform enumeration techniques
passive\_enum "$targetDomain"
active\_enum "$targetDomain"
brute\_force\_enum "$targetDomain" "$wordlist"
dns\_zone\_transfer "$targetDomain" "8.8.8.8" # Change DNS server as needed
google\_dorking "$targetDomain"
}
# Execute main function
main

Robin Joseph
Head of Security testing