Introduction
Subdomain takeover (sometimes called DNS takeover) occurs when an attacker claims control over a sub-domain that the legitimate organization no longer serves. By leveraging mis-configured DNS records that point to external services (e.g., S3 buckets, Azure blobs, GitHub Pages), the attacker can host arbitrary content under a trusted domain, bypassing many traditional security controls.
Why it matters: The compromised sub-domain inherits the reputation, SEO ranking, and brand trust of the parent domain. Attackers can use it for phishing, malware distribution, credential harvesting, or to bypass CSP/SSRF protections that whitelist the parent domain.
Real-world relevance: High-profile incidents such as the GitHub Pages takeover of status.example.com and the Azure storage takeover of static.corp.com have demonstrated that even large enterprises can fall victim to simple DNS oversights.
Prerequisites
- Fundamentals of DNS - understanding A, CNAME, and NS records.
- Basic subdomain enumeration using tools like
amassorsubfinder. - Familiarity with HTTP response codes (200, 404, 401) and common security-relevant headers (e.g.,
Content-Security-Policy,X-Frame-Options).
Core Concepts
At its core, a subdomain takeover hinges on a dangling DNS pointer. The DNS record (typically a CNAME) points to an external service that the owner has abandoned. When the external service is later claimed by an attacker, the DNS resolution now resolves to the attacker-controlled resource.
Key components:
- DNS Record Type - Most takeovers involve CNAME records, but A records pointing to decommissioned IPs (e.g., a terminated EC2 instance) also qualify.
- External Service Namespace - Cloud storage (S3, Azure Blob), CI/CD platforms (GitHub Pages, GitLab Pages), SaaS providers (Heroku, Netlify), and custom SaaS (e.g.,
app.myservice.com). - Verification Mechanism - Many services return a distinct HTTP status (often
404or a service-specific error page) when the resource does not exist. This is the signal an attacker looks for before claiming the resource.
Imagine a diagram where sub.example.com CNAME→ mybucket.s3.amazonaws.com. The bucket has been deleted, but DNS still points there. An attacker creates a bucket with the same name, gaining control of sub.example.com.
What is subdomain takeover and why it matters
A subdomain takeover is the act of hijacking a DNS record that points to an external service which is no longer provisioned by the legitimate owner. The attacker registers the missing resource (e.g., a cloud bucket, a GitHub repository) and instantly controls the sub-domain.
Why it matters:
- Brand Abuse - The attacker can host phishing pages that appear to come from the trusted domain.
- Bypass Whitelists - Many applications whitelist sub-domains for OAuth redirects, SSO, or CSP. A takeover defeats those controls.
- SEO Poisoning - Search engines index the malicious content under the original domain, boosting the attacker’s reach.
- Data Exfiltration - Some SSRF filters allow only
*.example.com. A compromised sub-domain can be used as a covert exfil channel.
Typical attack surface: orphaned DNS records and cloud services
The attack surface is surprisingly broad. Below are the most common orphaned configurations:
- Amazon S3 - Unclaimed bucket names (
mybucket.s3.amazonaws.com) after a bucket deletion. - Azure Blob Storage - Missing
.blob.core.windows.netcontainers. - Google Cloud Storage - Unregistered
storage.googleapis.combuckets. - GitHub Pages - CNAME pointing to
username.github.iowhere the repo has been removed. - Heroku - CNAME to
appname.herokuapp.comafter the app is destroyed. - Netlify, Vercel, Render - Similar pattern: CNAME →
*.netlify.app,*.vercel.app, etc. - Custom SaaS - Services that allocate sub-domains (e.g.,
tenant.myservice.com) but never release them on account termination.
Each of these services provides a simple HTTP endpoint that returns a predictable “resource not found” page. Attackers script the detection of these responses and claim the resource programmatically.
Risk assessment and impact scenarios
When evaluating risk, consider three axes:
- Asset Criticality - Is the parent domain used for authentication, payment, or internal communications?
- Visibility - Does the sub-domain appear in public marketing material, emails, or API documentation?
- Exploitability - How easy is it to claim the dangling resource? Some services require email verification, others allow instant claim via CLI.
Impact scenarios:
- Phishing via
login.example.com- Users are redirected to an attacker-controlled login page that harvests credentials. - Malware distribution via
cdn.example.com- The attacker hosts a malicious JavaScript payload that is automatically loaded by the legitimate site. - SSRF exfiltration via
api.example.com- An internal service that fetches URLs only from*.example.comcan be tricked into contacting the attacker’s server, leaking internal data.
In each case, the breach can be achieved without compromising the primary domain’s DNS zone, making detection harder.
Practical Examples
Below is a step-by-step walkthrough of discovering and exploiting a vulnerable GitHub Pages sub-domain.
- Enumerate sub-domains with
subfinder:subfinder -d example.com -o subdomains.txt - Identify CNAME records that point to GitHub:
while read sub; do dig +short CNAME $sub; done < subdomains.txt | grep github.io - Check HTTP response for a non-existent GitHub repo:
curl -s -o /dev/null -w "%{http_code}" https://blog.example.comIf the response is
404and the body contains “There isn’t a GitHub Pages site here”, the resource is likely unclaimed. - Claim the GitHub repository (requires a GitHub account):
git clone https://github.com/username/blog.example.com.git cd blog.example.com echo "<h1>Compromised!</h1>" > index.html git add index.html git commit -m "Initial commit" git push origin masterGitHub automatically publishes the site at
username.github.io/blog.example.com, and DNS now resolvesblog.example.comto the attacker-controlled page.
From here, the attacker can host phishing pages, inject malicious JavaScript, or simply use the domain for reputation-boosted spam.
Tools & Commands
- subfinder / amass - Fast sub-domain enumeration.
- dnsx - Probe DNS records and filter by provider (e.g.,
--provider github). - httprobe - Validate live HTTP services on discovered sub-domains.
- takeover - A dedicated Python tool that automates detection of vulnerable CNAMEs.
python3 takeover.py -d example.com -o results.txt - awscli / az cli / gcloud - Create the missing cloud resources programmatically.
aws s3api create-bucket --bucket vulnerable.example.com --region us-east-1
Defense & Mitigation
- Continuous DNS Auditing - Schedule automated scans (e.g., nightly
dnsx+takeover) to detect dangling CNAMEs. - Remove Unused Records - Enforce a policy that any DNS entry must have a corresponding active service. Use CI pipelines to validate.
- Implement DNS TTL Shortening - Reduce the window of exposure by using low TTLs (
300seconds) for dynamic sub-domains. - Use Provider-Specific Alerts - Enable bucket-deletion notifications (S3 EventBridge) and GitHub repository deletion webhooks.
- Lock Down CNAME Targets - Prefer A records for critical sub-domains where possible; avoid CNAMEs to third-party services unless absolutely required.
- Security Headers - Deploy CSP with
frame-ancestors 'none'andobject-src 'none'to limit abuse of a compromised sub-domain.
Common Mistakes
- Assuming a 404 means safe - Some services return
200 OKwith a generic “Not found” page. Always inspect the body. - Scanning only CNAMEs - A records pointing to decommissioned IPs can also be taken over via cloud-instance hijacking.
- Neglecting internal DNS - Private zones can be just as vulnerable, especially when internal services whitelist
*.corp.com. - One-off remediation - Removing a single record without a process will cause the problem to re-appear later.
Real-World Impact
In 2023, a Fortune-500 retailer suffered a phishing campaign that leveraged a takeover of login.payments.example.com. Attackers cloned the original login page, harvested 12,000 credentials, and the breach went undetected for weeks because the DNS zone remained unchanged.
My experience in red-team engagements shows that sub-domain takeovers are often the easiest foothold after gaining initial foothold in the network. They require minimal effort—sometimes a single aws s3api create-bucket—yet deliver high impact.
Trends: As organizations adopt more SaaS platforms, the number of externally-managed namespaces grows, expanding the attack surface. Automation tools (e.g., takeover, subjack) have lowered the barrier for attackers, making regular scanning a must-have practice.
Practice Exercises
- Lab Setup
- Create a test domain (e.g.,
lab.example.com) on a DNS provider you control. - Add a CNAME
orphan.lab.example.com→nonexistent-bucket.s3.amazonaws.com.
- Create a test domain (e.g.,
- Detect the Orphan
dnsx -d lab.example.com -type CNAME -silent | grep s3.amazonaws.com - Exploit
aws s3api create-bucket --bucket nonexistent-bucket --region us-east-1 aws s3api put-object --bucket nonexistent-bucket --key index.html --body <!DOCTYPE html><html><body><h1>Compromised</h1></body></html>Verify with curl -I that you now receive a 200 OK.
- Remediation
Delete the CNAME record or point it to a valid service. Document the change in your DNS change-log.
Further Reading
- “The Art of DNS Reconnaissance” - Black Hat 2022 presentation.
- OWASP Subdomain Takeover Cheat Sheet.
- Cloud provider documentation on bucket naming collisions (AWS S3, Azure Blob).
- Domain-specific “takeover” modules in
nucleifor automated scanning.
Summary
Subdomain takeover is a high-impact, low-effort attack that exploits orphaned DNS records pointing to external services. By continuously enumerating sub-domains, monitoring DNS changes, and enforcing strict lifecycle management of cloud resources, organizations can dramatically reduce the risk. Remember:
- Every CNAME is a potential foothold.
- Automation is both a threat (attack scripts) and a defense (scheduled scans).
- Integrate DNS hygiene into CI/CD pipelines and change-management processes.
Adopting these practices turns a common blind spot into a well-guarded perimeter.