Subdomain Takeover is a vulnerability that’s been covered quite extensively, especially in the bug bounty space, but I still see a lot of security professionals getting mixed up about how this happens and the potential impact of a takeover. So, having done a bit of research on this recently, I thought I’d share what I’ve learned in hopes it helps someone.
What is a Subdomain?
A subdomain is generally used as a way to create “sections” of a domain. These are created for a lot of different reasons, such as:
Testing Environments: Separating development and production environments
Organizational Structure: Separating functionality of different development teams or departments
Localization: us.example.com, eu.example.com
Logical Structure: Separating services or features
Cloud Service Mapping: Create a “human friendly” name to access resources like Cloudfront/S3, Azure Blob Storage, GitHub Pages, Heroku apps, Shopify page, etc.
It’s also worth noting that search engines consider subdomains as separate entities, so this could also be used for SEO purposes, though if I am honest, I don’t know how relevant that is anymore. Regardless, all subdomains are tied directly to the primary domain, or “apex” domain. You cannot create subdomains of a domain that you do not own, unless there is some underlying functionality in an application that would allow you to do this.
Subdomain Terminology
blog.example.com
“blog” = subdomain
“example” = apex domain
“.com” = top-level domain (TLD)
Subdomain resolution by cname
A "canonical name" (CNAME) record points from an alias domain to a "canonical" domain. A CNAME record is used in lieu of an A record, in order to use a domain or subdomain as an alias of another domain. This is most commonly used with cloud resources so that when a customer visits your site at blog.example.com, that you have hosted as a static site on an S3 bucket, they’re not clicking a link that does not seem to be related to your application, such as http://s3.amazonaws.com/{bucket-name}.
You can setup a subdomain to point to the “content source” via 2 methods - 301,302 redirects or CNAME resolution. 302 redirects will result in the browser displaying the destination URL (S3/Cloudfront domain xxxx.cloudfront.net) whereas a CNAME will have a “redirect” in the DNS lookup.
DNS Flow
User Request:
A user enters sub.example.com into their web browser.
Root Name Server Query:
The DNS resolver queries a root name server, which directs it to the TLD name server responsible for .com domains.
TLD Name Server Query:
The DNS resolver queries the TLD name server for sub.example.com, which points it to the authoritative name server for example.com.
Authoritative Name Server Query for example.com:
The DNS resolver queries the authoritative name server for example.com, which responds with a CNAME record indicating that sub.example.com is an alias for otherdomain.com.
Resolution of otherdomain.com:
The DNS resolver repeats steps 2-3 for otherdomain.com, and queries the authoritative name server for otherdomain.com.
Authoritative Name Server Query for otherdomain.com:
The DNS resolver queries the authoritative name server for otherdomain.com, which responds with an A record containing the IP address of otherdomain.com
IP Address Resolution:
The DNS resolver returns the IP address to the user's system.
Browser Request and Content Delivery:
The browser sends a request to the resolved IP address and displays the webpage to the user.
Attack Path
An step by step of how this vulnerability typically occurs:
Subdomain Configuration: An organization sets up a subdomain (e.g., blog.example.com) and points it to an external service, like a website builder, content delivery network, or cloud platform.
Service Removal: For some reason, the service associated with the subdomain is no longer used or is deleted. This could be due to a project being discontinued, moving to another platform, or some other operational change.
DNS Oversight: Crucially, the DNS entry that points the subdomain to the external service is not removed. This means the subdomain still references an address or endpoint that no longer exists under the organization's control.
Attack Execution: A malicious actor discovers this oversight. They then register or claim the abandoned service endpoint. Since the subdomain still points to this endpoint, the attacker now controls any content served from the subdomain. The way this is done is completely dependent on what service the DNS record is pointing to. For instance, if the CNAME is to an S3 bucket, but the bucket has been deleted, all an attacker needs to do is create a bucket with that same name! Other services are slightly more complicated and sometimes require some element of brute force to get around random naming, but just because the service assigns a name that the attacker does not control does not mean you are safe.
Impact of a Subdomain Takeover
The usual suspects
Phishing campaigns - now featuring your domain name!
Brand damage
Malware distribution
Bypassing application controls
CSP/Same-Origin Policy bypass
It’s very common to include subdomains in a CSP to allow for delivery of content to support the application
If an XSS is present in your app and the CSP allows wildcard subdomains, now you’re pwned subdomain can deliver malicious JS!
WAF bypass if policy is too lax
Authentication bypass/Account Takeover via wildcard cookie scoping
Case Study 1 - Cookie sent for every request to *.example.com
Here is a summary of a redacted Subdomain Takeover BBP Report from Hacktus. I highly recommend reading the whole post as it does a great job of showing how an attacker can use this vulnerability to create very impactful bugs.
AspNetCore.Cookies being shared on all requests/subdomains
Found valid subdomain takeover on Azurewebsites.net page
Collect tokens of logged in users by tricking them into visiting your taken over subdomain (phishing/social engineering)
Profit!
Case Study 2 - Wildcard Scoped Cookies
Another great BBP Report from Arne Swinnen here. Essentially, he was able to find a subdomain vulnerable to takeover, which then was escalated into a full authentication bypass! This report is very thorough and there are several steps in the escalation, so rather than rehashing it, here is a brief summary. But again, highly recommend reading the full report to understand how a simple subdomain takeover can have massive consequences.
_csid cookie scoped for “https://*.uber.com”
Used as a temporary token in Oauth process
Some CSRF and cookie stealing fun via phishing or social engineering
Authentication bypass!
Traditional Event Based Monitoring won’t work!
One thing that I’ve seen happen with defenders trying to effectively detect an issue like this is being too focused on event based triggers to alert them that a subdomain could be taken over. However, this is not really effective unless you are tracking every single time a cloud resource is being deleted. And in almost every organization that is deploying via the cloud today, this is a nearly impossible task. Resources are deleted and created constantly and you’d end up looking for a needle in a haystack. And defenders hate excessive noise.
Detection via Asset Management
The best way to tackle this is to focus on Asset Management. Knowing what exists externally to your organization is absolutely key here. You cannot defend subdomains if you do not know which subdomains exist. This can sometimes be challenging depending on how your organization manages it’s DNS records.
However, if you’re lucky and your organization uses something like Route53 to programmatically manage all DNS records, you can and should use this data! Regularly scrape those files to see what subdomains exist and programmatically check their DNS records and how they resolve. There are fingerprints of many different services available that help you determine if a subdomain is returning a response that indicates it’s vulnerable. One of my favorite repositories for this is Can I takeover XYZ. The repo not only tells you what services are vulnerable, but how to fingerprint them, and how to carry out the attack! You could also do something as simple as use the AWS CLI to see if a CNAME is pointing to a resource that no longer exists. Point being, there’s a lot of options for automation.
When DNS Records are not easily viewable
I’ve been in situations where there is very little visibility into DNS records, which tends to happen in smaller organizations where they are using a more basic registrar and you cannot easily share access to the service without also handing over keys to create records. If this is your situation, one way to work on tackling this problem is using open source tools to help you identify as many subdomains as possible. This won’t always be full proof, but it’s a step in the right direction. You can make use of tools like Amass, ShuffleDNS, Sublist3r, etc. to give you this data. Once you have a list of subdomains, you can use a tool like Subjack to quickly check them, or you can create your own fingerprinting logic with the Takeover XYZ repo I mentioned before.
You might also be able to find other bug bounty recon tools that will aggregate data from various tools I mentioned above, giving you the best possible shot at a holistic view, without actually being able to get to a source of truth internally. One such tool is from a coworker/friend, Harrison Richardson, is the ars0n-framework. The challenge with using this is that it’s not very straight forward to get the data out of this and into a format that allows for programmatically saving this data elsewhere. A team of my colleagues and I are currently working on a tool that is heavily inspired by this framework, but from an API first standpoint to help teams that need a tool to do this sort of thing. I am hoping we can release this tool early next year! The goal is to create a container driven “SOAR” of sorts for identifying your external attack surface using OSS tools and storing that data in a database for other parts of your team/organization to ingest for whatever purposes best suit you. It may also end up being an excellent bug bounty tool ;).
Internal Processes
Lastly, I highly recommend creating a centralized pattern for creating/deleting new subdomains in your organization. This can sometimes be owned by a DevOps team as well. But the main point is having some kind of a record of what’s being done on a regular basis and ensuring that these details get reviewed to ensure that nothing slips through the cracks. The best way is to manage it via code with R53 or similar so that a pull request and peer review is required to make any changes. This isn’t always something a smaller or younger organization has, which only makes having this process that much more important!
Summary
Monitoring your subdomains is extremely important and although this is not a new topic, lots of companies still fall prey to this. Given a determined enough attacker, this can and will be used against you! The good news is, it’s a very solvable problem with automation, time, and thought. Good luck!