Findomain
Findomain is a high-speed, passive subdomain discovery tool that uses multiple sources including certificate transparency logs, DNS databases, and web archives to enumerate subdomains.
Installation
From Releases
# Linux
wget https://github.com/Findomain/Findomain/releases/latest/download/findomain-linux
chmod +x findomain-linux
sudo mv findomain-linux /usr/local/bin/findomain
# macOS
wget https://github.com/Findomain/Findomain/releases/latest/download/findomain-osx
chmod +x findomain-osx
sudo mv findomain-osx /usr/local/bin/findomain
# Windows
# Download from https://github.com/Findomain/Findomain/releases
# Add to PATH
From Source
git clone https://github.com/Findomain/Findomain.git
cd Findomain
cargo build --release
sudo cp target/release/findomain /usr/local/bin/
Verify Installation
findomain --version
findomain --help
Basic Commands
| Command | Description |
|---|---|
findomain -t example.com | Find subdomains for domain |
findomain -t example.com -o txt | Output as TXT file |
findomain -t example.com -f results.txt | Save to file |
findomain -t example.com -a | Use all sources |
findomain -t example.com --unique-output subdomains.txt | Deduplicate results |
findomain -h | Show help |
findomain --version | Show version |
Subdomain Enumeration
Basic Enumeration
# Simple enumeration
findomain -t example.com
# Output to file
findomain -t example.com -f subdomains.txt
# Different output formats
findomain -t example.com -o txt
findomain -t example.com -o json
findomain -t example.com -o csv
# Use all available sources
findomain -t example.com -a
# Specific output file name
findomain -t example.com --output subdomains
Multiple Domains
# Enumerate from file
findomain -l domains.txt
# Process multiple domains with output
for domain in $(cat domains.txt); do
findomain -t $domain -f results/$domain.txt
done
# Combine results
cat results/*.txt | sort -u > all_subdomains.txt
Advanced Options
# Quiet mode (no verbose output)
findomain -t example.com -q
# Use specific resolvers
findomain -t example.com -r 8.8.8.8 1.1.1.1
# Monitor for new subdomains (enterprise feature)
findomain -t example.com --monitoring
# Exclude specific subdomains
findomain -t example.com --exclude-subdomains analytics,cdn
# Resolve subdomains
findomain -t example.com -r
# Get only alive subdomains
findomain -t example.com -a | while read sub; do
timeout 1 dig +short $sub @8.8.8.8 > /dev/null && echo $sub
done
OSINT & Reconnaissance
Subdomain Enumeration Workflow
#!/bin/bash
# Comprehensive subdomain enumeration
TARGET="example.com"
OUTPUT_DIR="reconnaissance/$TARGET"
mkdir -p "$OUTPUT_DIR"
# Step 1: Enumerate subdomains
echo "[*] Enumerating subdomains..."
findomain -t $TARGET -a -f "$OUTPUT_DIR/subdomains_all.txt"
# Step 2: Deduplicate
sort -u "$OUTPUT_DIR/subdomains_all.txt" > "$OUTPUT_DIR/subdomains_unique.txt"
echo "[+] Found $(wc -l < $OUTPUT_DIR/subdomains_unique.txt) unique subdomains"
# Step 3: Resolve DNS
echo "[*] Resolving DNS..."
while IFS= read -r subdomain; do
dig +short $subdomain | grep -v '^$' && echo "$subdomain"
done < "$OUTPUT_DIR/subdomains_unique.txt" > "$OUTPUT_DIR/resolved.txt"
# Step 4: Identify alive hosts
echo "[*] Identifying alive hosts..."
while IFS= read -r subdomain; do
timeout 2 curl -s -o /dev/null -w "%{http_code}" http://$subdomain 2>/dev/null && echo "$subdomain"
done < "$OUTPUT_DIR/subdomains_unique.txt" > "$OUTPUT_DIR/alive_http.txt"
# Step 5: Check for wildcard DNS
echo "[*] Testing for wildcard..."
dig $TARGET | grep -q "ANSWER: 0" && echo "No wildcard" || echo "Possible wildcard detected"
# Summary
echo ""
echo "=== Enumeration Summary ==="
echo "Total subdomains: $(wc -l < $OUTPUT_DIR/subdomains_unique.txt)"
echo "Resolved: $(wc -l < $OUTPUT_DIR/resolved.txt)"
echo "Alive (HTTP): $(wc -l < $OUTPUT_DIR/alive_http.txt)"
Bulk Organization Reconnaissance
#!/bin/bash
# Enumerate multiple targets
TARGETS="targets.txt"
OUTPUT_DIR="recon_results"
mkdir -p "$OUTPUT_DIR"
while IFS= read -r domain; do
echo "[*] Processing $domain..."
# Enumerate
findomain -t $domain -a -f "$OUTPUT_DIR/$domain.txt"
# Get counts
count=$(wc -l < "$OUTPUT_DIR/$domain.txt")
echo " Found: $count subdomains"
done < "$TARGETS"
# Create summary
echo "=== Enumeration Summary ===" > "$OUTPUT_DIR/SUMMARY.txt"
for file in "$OUTPUT_DIR"/*.txt; do
domain=$(basename "$file" .txt)
count=$(wc -l < "$file")
echo "$domain: $count subdomains" >> "$OUTPUT_DIR/SUMMARY.txt"
done
echo "[+] Summary saved to $OUTPUT_DIR/SUMMARY.txt"
Subdomain Filtering & Analysis
#!/bin/bash
# Analyze and filter subdomains
SUBDOMAINS="subdomains.txt"
# Filter development subdomains
echo "=== Development Subdomains ==="
grep -E "(dev|test|staging|qa|sandbox|internal)" $SUBDOMAINS
# Filter by common patterns
echo "=== API Subdomains ==="
grep -E "(api|gateway|rest|graphql)" $SUBDOMAINS
# Filter by potential vulnerabilities
echo "=== Potentially Interesting ==="
grep -E "(admin|debug|backup|old|legacy|temp)" $SUBDOMAINS
# Filter wildcard subdomains
echo "=== Wildcard Matches ==="
grep -E "^[a-z0-9-]+\." $SUBDOMAINS | sort | uniq
# Identify by IP range
echo "=== Subdomains by IP ==="
while IFS= read -r sub; do
ip=$(dig +short $sub @8.8.8.8 | head -1)
[ ! -z "$ip" ] && echo "$sub -> $ip"
done < $SUBDOMAINS
Integration with Other Tools
#!/bin/bash
# Chain with other OSINT tools
DOMAIN="example.com"
# Enumerate subdomains
echo "[*] Enumerating with findomain..."
findomain -t $DOMAIN -a > subdomains.txt
# Get HTTP headers (if curl available)
echo "[*] Checking HTTP headers..."
while IFS= read -r sub; do
echo "=== $sub ==="
curl -s -I http://$sub 2>/dev/null | head -5
done < subdomains.txt
# Probe for open ports (if nmap available)
echo "[*] Port scanning..."
cat subdomains.txt | xargs -I {} sh -c 'nmap -p 80,443 -sS {} 2>/dev/null | grep open' 2>/dev/null
# Screenshot (if available)
echo "[*] Web reconnaissance..."
while IFS= read -r sub; do
echo "Checking $sub..."
timeout 5 curl -s http://$sub > /tmp/$sub.html 2>/dev/null && \
echo " Status: Success" || echo " Status: Failed"
done < subdomains.txt
DNS & Resolution
DNS Resolution Techniques
# Resolve all subdomains
while IFS= read -r subdomain; do
dig +short $subdomain
done < subdomains.txt > ips.txt
# Reverse DNS lookup
dig -x 1.2.3.4
# Zone transfer (if permitted)
dig @ns1.example.com example.com axfr
# DNS wildcard detection
dig *.example.com
# Query specific record types
dig example.com A
dig example.com AAAA
dig example.com CNAME
dig example.com MX
dig example.com NS
dig example.com TXT
Resolve and Filter Active Hosts
#!/bin/bash
# Find only responding subdomains
SUBDOMAINS="subdomains.txt"
ACTIVE="active_subdomains.txt"
echo "" > $ACTIVE
while IFS= read -r sub; do
# Resolve
ip=$(dig +short $sub @8.8.8.8 A | head -1)
# Check if resolved
if [ ! -z "$ip" ] && [ "$ip" != ";" ]; then
# Verify with ping
if timeout 1 ping -c 1 $sub > /dev/null 2>&1; then
echo "$sub ($ip)" >> $ACTIVE
fi
fi
done < $SUBDOMAINS
echo "Active subdomains: $(wc -l < $ACTIVE)"
Data Export & Analysis
Export Findings
# JSON export for parsing
findomain -t example.com -o json | jq '.subdomains[]'
# CSV format for spreadsheet
findomain -t example.com -o csv > subdomains.csv
# Text file for further processing
findomain -t example.com -o txt
# Combine multiple exports
find . -name "*.txt" -exec cat {} \; | sort -u > combined.txt
Create Report
#!/bin/bash
# Generate enumeration report
DOMAIN="example.com"
REPORT="report_$DOMAIN.txt"
cat > $REPORT << EOF
=== SUBDOMAIN ENUMERATION REPORT ===
Domain: $DOMAIN
Date: $(date)
Tool: Findomain
=== RESULTS ===
EOF
echo "" >> $REPORT
echo "Total Subdomains Found: $(findomain -t $DOMAIN -a | wc -l)" >> $REPORT
echo "" >> $REPORT
echo "Top Subdomains:" >> $REPORT
findomain -t $DOMAIN -a | head -20 >> $REPORT
echo "" >> $REPORT
echo "=== END REPORT ===" >> $REPORT
cat $REPORT
Monitoring & Continuous Enumeration
Periodic Subdomain Checks
#!/bin/bash
# Monitor for new subdomains
DOMAIN="example.com"
HISTORY_DIR="subdomain_history"
mkdir -p "$HISTORY_DIR"
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
CURRENT="$HISTORY_DIR/subdomains_$TIMESTAMP.txt"
PREVIOUS="$HISTORY_DIR/subdomains_latest.txt"
# Get current subdomains
findomain -t $DOMAIN -a | sort > $CURRENT
# Compare with previous
if [ -f "$PREVIOUS" ]; then
echo "=== NEW SUBDOMAINS ==="
diff "$PREVIOUS" "$CURRENT" | grep '^>'
echo "=== REMOVED SUBDOMAINS ==="
diff "$PREVIOUS" "$CURRENT" | grep '^<'
fi
# Update latest
cp $CURRENT "$PREVIOUS"
# Log summary
echo "$TIMESTAMP: $(wc -l < $CURRENT) subdomains" >> "$HISTORY_DIR/history.log"
Cron Job for Daily Enumeration
# Add to crontab: crontab -e
0 2 * * * /opt/scripts/enumerate_subdomains.sh
# Script: /opt/scripts/enumerate_subdomains.sh
#!/bin/bash
TARGET="example.com"
OUTPUT="/var/log/subdomain_enum/$TARGET/$(date +\%Y\%m\%d).txt"
mkdir -p $(dirname "$OUTPUT")
findomain -t $TARGET -a > $OUTPUT 2>&1
echo "Enumerated $(wc -l < $OUTPUT) subdomains on $(date)" >> /var/log/subdomain_enum.log
Best Practices
- Run enumeration regularly to catch new subdomains
- Combine results from multiple tools for completeness
- Filter results by organizational relevance
- Verify findings before reporting
- Look for patterns in subdomain naming
- Check for subdomains on different TLDs
- Document all findings with timestamps
- Use quiet mode in scripts to reduce noise
Troubleshooting
No Results
# Check internet connectivity
ping 8.8.8.8
# Verify domain spelling
findomain -t typodomain.com
# Try with all sources
findomain -t example.com -a
# Check for DNS issues
dig example.com
Slow Performance
# Run in quiet mode
findomain -t example.com -q
# Limit to file output only
findomain -t example.com -f results.txt > /dev/null
Resources
Last updated: 2026-03-30