Although I have written multiple posts about subdomain takeover, I realized that there aren't many posts covering basics of subdomain takeover and the whole "problem statement." This post aims to explain (in-depth) the entire subdomain takeover problem once again, along with results of an Internet-wide scan that I performed back in 2017.
Subdomain takeover is a process of registering a non-existing domain name to gain control over another domain. The most common scenario of this process follows:
- Domain name (e.g., sub.example.com) uses a CNAME record to another domain (e.g., sub.example.com CNAME anotherdomain.com).
- At some point in time, anotherdomain.com expires and is available for registration by anyone.
- Since the CNAME record is not deleted from example.com DNS zone, anyone who registers anotherdomain.com has full control over sub.example.com until the DNS record is present.
The implications of the subdomain takeover can be pretty significant. Using a subdomain takeover, attackers can send phishing emails from the legitimate domain, perform cross-site scripting (XSS), or damage the reputation of the brand which is associated with the domain. You can read more about implications (risks) in my other post.
Subdomain takeover is not limited to CNAME records. NS, MX and even A records (which are not subject to this post) are affected as well. This post deals primarily with CNAME records. However, use cases for NS and MX records are presented where needed.
DNS delegation using a CNAME record is entirely transparent to the user, i.e., it happens in the background during DNS resolution. The picture below illustrates the behavior of a web browser for the domain name which has CNAME record in place.
Note that a web browser is implicitly putting trust to anything that DNS resolver returns. Such trust means that when an attacker gains control over DNS records, all web browser security measurements (e.g., same-origin policy) are bypassed. This presents a considerable security threat since subdomain takeover breaks the authenticity of a domain which can be leveraged by an attacker in several ways. As will be shown in later, TLS/SSL does not fix this problem since subdomain takeover is not regular Man-in-the-middle style attack.
CNAME subdomain takeover. One of the primary types of CNAME subdomain takeover is the scenario when a canonical domain name is a regular Internet domain (not one owned by cloud providers as will be explained below). The process of detecting whether some source domain name is vulnerable to CNAME subdomain takeover is quite straightforward:
Given the pair of source and canonical domain names, if the base domain of a canonical domain name is available for registration, the source domain name is vulnerable to subdomain takeover.
The noteworthy thing in the process is ,,the base domain of a canonical domain name". That is because the canonical domain name might be in the form of a higher-level domain. If a base domain is available for registration, the higher-level domain names can be easily recreated in the DNS zone afterward.
Checking the availability of base domain names can be achieved using domain registrars such as Namecheap. One might think that testing a DNS response status for NXDOMAIN is sufficient indication that the domain name is available for registration. Note however that it is not the case since there are cases where domain name responds with NXDOMAIN but cannot be registered. Reasons include restricted top-level domains (e.g., .GOV, .MIL) or reserved domain names by TLD registrars.
NS subdomain takeover. The concept of subdomain takeover can be naturally extended to NS records: If the base domain of canonical domain name of at least one NS record is available for registration, the source domain name is vulnerable to subdomain takeover.
One of the problems in subdomain takeover using NS record is that the source domain name usually has multiple NS records. Multiple NS records are used for redundancy and load balancing. The nameserver is chosen randomly before DNS resolution. Suppose that the domain sub.example.com has two NS records: ns.vulnerable.com and ns.nonvulnerable.com. If an attacker takes over the ns.vulnerable.com, the situation from the perspective of the user who queries sub.example.com looks as follows:
- Since there are two nameservers, one is randomly chosen. This means the probability of querying nameserver controlled by an attacker is 50%.
- If user's DNS resolver chooses ns.nonvulnerable.com (legitimate nameserver), the correct result is returned and likely being cached somewhere between 6 and 24 hours.
- If user's DNS resolver chooses ns.vulnerable.com (nameserver owned by an attacker), an attacker might provide a false result which will also be cached. Since an attacker is in control of nameserver, she can set TTL for this particular result to be for example one week.
MX subdomain takeover. Compared to NS and CNAME subdomain takeovers, MX subdomain takeover has the lowest impact. Since MX records are used only to receive e-mails, gaining control over canonical domain name in MX record only allows an attacker to receive e-mails addressed to source domain name. Although the impact is not as significant as for CNAME or NS subdomain takeover, MX subdomain takeover might play a role in spear phishing attacks and intellectual property stealing.
Cloud services are gaining popularity in recent years. One of the basic premises of the cloud is to offload its users from setting up their infrastructure. Organizations are switching from an on-premise setup to alternatives such as cloud storage, e-commerce in a cloud, and platform-as-a-service, to name a few.
After a user creates a new cloud service, the cloud provider in most cases generates a unique domain name which is used to access the created resource. Because registering a domain name via TLD registrar is not very convenient because of a large amount of cloud service customers, cloud providers opt to use subdomains. The subdomain identifying unique cloud resource often comes in the format of name-of-customer.cloudprovider.com, where cloudprovider.com is a base domain owned by the particular cloud provider.
If the cloud service registered by an organization is meant to be public (e.g., e-commerce store), the particular organization might want to have it present as part of their domain. The main reason behind this is branding: shop.organization.com looks better than organization.ecommerceprovider.com. In this case, the organization has two choices:
HTTP 301/302 redirect — 301 and 302 are HTTP response codes that trigger a web browser to redirect the current URL to another URL. In the context of cloud services, the first request is made to a domain name of an organization (e.g., shop.organization.com) and then redirect is made to a domain name of cloud providers (e.g., organization.ecommerceprovider.com).
CNAME record — Using this method, the ,,redirect" happens during DNS resolution. The organization sets CNAME record, and all traffic is automatically delegated to the cloud provider. Using this method, the URL in the user's browser stays the same. Note however that the particular cloud service must support delegation using CNAME records.
If the CNAME record method is used, the possibility of subdomain takeovers comes into play. Even though the cloud provider owns the base domain of a canonical domain name, subdomain takeover is still possible as is presented in the next sections.
The providers in the subsequent sections were chosen based on three primary reasons:
- Prevalence — Based on statistics on CNAME records, cloud providers domains with the highest usage in CNAME records were prioritized.
- Support for CNAME records — As explained above, cloud provider needs to support CNAME delegation. Cloud providers realize that customers request such behavior and the most popular cloud providers already support it.
- Domain ownership verification — The chosen cloud providers are not verifying the ownership of the source domain name. Since the owner does not need to be proven, anyone can use expired cloud configuration to realize subdomain takeover.
Amazon CloudFront is a Content Delivery Network (CDN) in Amazon Web Services (AWS). CDN distributes copies of web content to servers located in different geographic locations (called points of presence). When a user makes a request to CDN, the closest point of presence is chosen based on visitors location to lower the latency. CDNs are utilized by organizations, mainly to distribute media files such as video, audio, and images. Other advantages of CDNs include Denial of Service attacks protection, reduced bandwidth, and load balancing in case of high traffic spikes.
CloudFront uses Amazon S3 as a primary source of web content. Amazon S3 is another service offered by AWS. It is a cloud storage service (S3 is an abbreviation for Simple Storage Service) which allows users to upload files into so-called buckets, which is a name for logical groups within S3.
CloudFront works with the notion of distributions. Each distribution is a link to specific Amazon S3 bucket to serve the objects (files) from. When the new CloudFront distribution is created, a unique subdomain is generated to provide access. The format of this subdomain is SUBDOMAIN.cloudfront.net. The SUBDOMAIN part is produced by CloudFront and cannot be specified by a user.
In addition to a randomly generated subdomain, CloudFront includes a possibility to specify an alternate domain name for accessing the distribution. This works by creating CNAME record from alternate domain name to subdomain generated by CloudFront. Although Amazon does not provide documentation about the internal CloudFront concepts, the high-level architecture can be deducted from its behavior. Based on the geographic location, DNS query to any subdomain of cloudfront.net leads to the same A records (in the same region). This indicates that CloudFront is using the virtual hosting setup in the backend. After the HTTP request arrives, CloudFront's edge server determines the correct distribution based on HTTP Host header. Documentation also supports this theory as it states: ,,You cannot add an alternate domain name to a CloudFront distribution if the alternate domain name already exists in another CloudFront distribution, even if your AWS account owns the other distribution"". Having multiple alternate domains pointing to one distribution is correct, however, having the same alternate domain name present in multiple distributions is not.
Therefore to correctly handle alternate domain names, CloudFront needs to know beforehand to which distribution the alternate domain name is attached. In other words, having CNAME record configured is not enough, the alternate domain name needs to be explicitly set in distribution settings.
The problem with alternate domain names in CloudFront is similar to problems explained in Regular Domains section. Let's assume that sub.example.com has a CNAME record set to d1231731281.cloudfront.net. When there is no sub.example.com registered in any CloudFront distribution as an alternate domain name, subdomain takeover is possible. Anyone can create a new distribution and set sub.example.com as an alternate domain name in its settings. Note that however, the newly created CloudFront subdomain does not need to match the one specified in the CNAME record (d1231731281.cloudfront.net). Since CloudFront uses a virtual hosting setup, the correct distribution is determined using HTTP Host header and not DNS record.
The picture below shows the error message that is presented after HTTP request to an alternate domain name which has the DNS CNAME record to CloudFront in place but is not registered in any CloudFront distribution.
This error message is a solid indication of the possibility of subdomain takeover. Nevertheless, the two exceptions need to be taken into account:
- HTTP / HTTPS only distributions — CloudFront allows specifying whether the distribution is HTTP-only or HTTPS-only. Switching HTTP to HTTPS might provide correct responses for some distributions.
- Disabled distribution — Some distributions might be disabled. Disabled distribution is no longer actively serving content while still preserving its settings. It means that some alternate domain name might be throwing an error message after HTTP request. However, it is even registered inside the disabled distribution and thus is not vulnerable to subdomain takeover. The correct way to determine whether an alternate domain is registered inside some distribution is to create a new distribution and set the alternate domain name. If the registration process does not throw an error, the custom domain is vulnerable to subdomain takeover. The screenshot below shows the error that is presented after the user tries to register the alternate domain name which is already present in some other CloudFront distribution.
As presented in the case of CloudFront, subdomain takeover is possible even on cloud services which do not have its base domain available for registration. However, since cloud services provide a way of specifying alternate domain names (CNAME records), the possibility of subdomain takeover is still present. This section provides a quick overview of other cloud services which work very similarly to CloudFront (virtual hosting architecture).
Amazon S3 — Amazon S3 was briefly mentioned in previously. The default base domain used to access the bucket is not always the same and depends on the AWS region that is used. The full list of Amazon S3 base domains is available in AWS documentation. Similarly to CloudFront, Amazon S3 allows specifying the alternate (custom) domain name to access the bucket's content.
Heroku — Heroku is a Platform-as-a-Service provider which enables deployment of an application using simple workflow. Since access to the application is needed, Heroku exposes the application using subdomain formed on herokuapp.com. However, it is also possible to specify the custom domain name to access the deployed application.
Shopify — Shopify provides a way of creating and customizing e-commerce stores in the cloud. The default subdomain to access the store is built on myshopify.com. As services described before, Shopify allows specifying alternate domain names. Noteworthy is that Shopify verifies correct CNAME record configuration. However, this verification is not domain ownership verification. Shopify only checks for accurate CNAME record that is present in the alternate domain's DNS zone. This verification, therefore, does not prevent subdomain takeovers.
GitHub — GitHub is a version control repository for Git. GitHub also allows free web hosting using their GitHub Pages project. This web hosting is usually used for project's documentation, technical blogs, or supporting web pages to open-source projects. GitHub Pages supports custom domain name in addition to default domain name under github.io.
Microsoft Azure — Microsoft Azure is a more prominent cloud provider, similar to AWS. It is different compared to the cloud services mentioned above in that it does not provide a virtual hosting architecture. Simply put, for each cloud service, Azure creates own virtual machine with own IP address. Therefore the mapping between a domain name and IP address is unambiguous (one-to-one mapping). Noteworthy is that since this is not a regular virtual hosting setup, configuring CNAME record does not necessarily have to be explicitly defined in the resource settings. Azure provides multiple cloud services but the ones discussed in this thesis have default domains of cloudapp.net and azurewebsites.net. Its documentation describes setting the link between the domain name and Azure resource using A or CNAME records (pointing to one of the two domains mentioned previously). An interesting observation is that for A records, Azure does a domain ownership verification using TXT records. However, it is not the case for a CNAME record, and subdomain takeover is, therefore, possible even in the case of Microsoft Azure.
For an extended listing of affected cloud providers, I highly recommend checking "Can I take over XYZ?" guide.
Project Sonar can be used to show the prevalence of subdomain takeover across the Internet. Because Project Sonar already contains resolved CNAME records, it is pretty straightforward to automate scanning for subdomain takeover across the Internet. This section explains its results.
Chain of CNAME records. In some instances, CNAME records might form CNAME record chains. Let's have the domain sub.example.com which has a CNAME record to sub.example1.com. If in turn, sub.example1.com has a CNAME record to sub.example2.com a three-way chain is formed:
sub.example.com -> sub.example1.com -> sub.example2.com
In such cases, when the base domain of last domain in the chain (example2.com) is available for registration both sub.example1.com and sub.example.com are affected. Fortunately, Project Sonar implicitly contains all CNAME references in the chain. For a chain given above, even though there is no direct CNAME record from sub.example.com to sub.example2.com, Project Sonar contains this record. Therefore, no direct changes need to be made to the automation tool to support CNAME record chains in Project Sonar.
The scanning was performed using a custom automation tool which I don't plan to release yet. The tool was able to scan cloud provider domains and found 12,888 source domain names vulnerable to subdomain takeover (November 2017). The cloud provider distribution follows:
Some parts of this post are excerpts from my Master's Thesis.
Check out my other posts about subdomain takeovers:
- Subdomain Takeover: Thoughts on Risks
- Subdomain Takeover: Going beyond CNAME
- Subdomain Takeover: Proof Creation for Bug Bounties
- Subdomain Takeover: Finding Candidates
Until next time!