Subdomain Takeover: Detection, Exploitation & Prevention

How dangling DNS records lead to subdomain takeovers, how to find them at scale, and how to prevent them in your own infrastructure.

web-securitybug-bountyrecontutorial

What Is a Subdomain Takeover?

A subdomain takeover happens when a DNS record for a subdomain points to a service that no longer exists — and an attacker can claim that service.

Classic scenario:

  1. Company creates staging.example.com → points to a Heroku app
  2. Company deletes the Heroku app but forgets to remove the DNS record
  3. Attacker creates a new Heroku app with the same name
  4. staging.example.com now serves attacker-controlled content

The attacker can now:

  • Serve phishing pages on a trusted domain
  • Steal cookies if SameSite=None and no __Host- prefix
  • Bypass CSP policies (the subdomain is trusted)
  • Issue certificates for the subdomain via certain CAs

Detection

Manual Check

# Step 1: Enumerate subdomains
subfinder -d example.com -silent | tee subdomains.txt
amass enum -passive -d example.com >> subdomains.txt
sort -u subdomains.txt > subdomains-unique.txt

# Step 2: Check which ones resolve
cat subdomains-unique.txt | dnsx -silent | tee resolving.txt

# Step 3: Look for NXDOMAIN on CNAMEs (the vulnerability pattern)
cat subdomains-unique.txt | dnsx -cname -silent

Automated Scan with Nuclei

# Use the nuclei subdomain-takeover templates
nuclei -l subdomains.txt -t ~/nuclei-templates/takeovers/ -o results.txt

# Verbose for debugging
nuclei -l subdomains.txt -t ~/nuclei-templates/takeovers/ -v

Checking a Specific CNAME

# Get the CNAME chain
dig CNAME staging.example.com +short

# Output example:
# myapp.herokuapp.com.

# Now check if that Heroku app exists
curl -sI https://myapp.herokuapp.com | head -5
# HTTP/2 404 — "No such app" = potentially vulnerable

Fingerprints by Provider

ProviderVulnerable Response
HerokuNo such app
GitHub PagesThere isn't a GitHub Pages site here
NetlifyNot Found - Request ID:
AWS S3NoSuchBucket
FastlyFastly error: unknown domain
ZendeskHelp Center Closed

Exploitation (Lab / Bug Bounty Only)

# GitHub Pages example
# 1. Create a repo named the same as the target subdomain
# 2. Enable GitHub Pages
# 3. Create a CNAME file:
echo "staging.example.com" > CNAME
git add CNAME && git commit -m "takeover" && git push

# Verify
curl -sI https://staging.example.com
# Should now serve your GitHub Pages content

Ethics note: Only test on domains you own or have explicit permission to test. For bug bounties, report immediately — don’t host anything malicious to “prove” the takeover.

Prevention

# Audit all your DNS records regularly
# List all CNAMEs in your zone:
dig axfr example.com @your-nameserver

# Or using a cloud provider CLI (AWS example):
aws route53 list-resource-record-sets \
  --hosted-zone-id YOURZONEID \
  --query "ResourceRecordSets[?Type=='CNAME']"

Process fixes:

  • Add DNS record removal to your service decommission checklist
  • Run a weekly automated scan with Nuclei against your own domains
  • Use short TTLs on CNAME records pointing to third-party services (easier to clean up)

References