Subdomain Takeover: Proof Creation for Bug Bounties

The post about subdomain takeover from last week received great feedback. I decided to follow-up and explain the process of actually taking over "vulnerable" subdomain. I noticed that multiple bug bounty programs started explicitly listing subdomain takeover as in-scope submission. In fact, the rewards are quite high:

Although many bug bounty programs are generous, they require you to provide proof of concept that the takeover is indeed possible. In this post, I explain how to verify whether subdomain takeover is possible and provide you with a step-by-step instructions for PoC creation (or SOP). As you may know, subdomain takeover is usually (but not necessarily) associated with cloud providers - the process is explained for top three takeover-prone cloud providers.

UPDATE: Refer to can-i-takeover-xyz as primary project for subdomain takeover PoC. This post acts as extended documentation with screenshots and a deeper explanation.

Before we start, you should be familiar with basic principles of subdomain takeover. There are numerous tools on GitHub which provide subdomain takeover verification:

Eventhough these tools provide nice heuristics about possible subdomain takeover, they sometimes contain false positives due to several restrictions given by the individual cloud provider. In the sections below, the manual verification snippet is provided for each domain. The naming convention for different types of domains follows:

Amazon S3

Amazon S3 is a storage service that works with concepts of buckets. Buckets are logical units of storage. After you create a bucket, a unique subdomain is generated for it. Sounds familiar?

Amazon S3 follows pretty much the same concept of virtual hosting as CloudFront does. You can read about S3 virtual hosting here. There is only one thing I want to mention. S3 buckets might be configured as website hosting to serve static content as web servers. If the canonical domain name has website in it, the S3 bucket is specified as Website hosting. I suspect that non-website and website configured buckets are handled by separate load balancers, and therefore they don't work with each other. The only difference will be in the bucket creation where correct website flag needs to be set if necessary.

If everything went without any errors, congratulations, the takeover is complete. The files will be present on appropriate URL path. If you uploaded file poc, then it will be http://sub.example.com/poc and so on.

GitHub Pages

GitHub provides 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.

Verification

CNAME record looks should look something like this:

sub.example.com 60 IN CNAME subexamplecom.github.io

I use the following regex to check the correct CloudFront canonical domain name:

Takeover

Set Repository name to canonical domain name (i.e., {something}.github.io from CNAME record)

Click Create repository

Push content using git to a newly created repo. GitHub itself provides the steps to achieve it

Switch to Settings tab

In GitHub Pages section choose master branch as source

Click Save

After saving, set Custom domain to source domain name (i.e., the domain name which you want to take over)

Click Save

If everything went without any errors, congratulations, the takeover is complete.

Heroku

Heroku is a popular PaaS provider. In our context, it has the same virtual hosting concept as other cloud providers. Various *.herokudns.com subdomain respond with the same set of A records. HTTP Host matters for correct domain resolution (as in other providers). There is also a possibility to upload own certificate to work on a custom domain as well (e.g., GitHub Pages doesn't support this, and thus you cannot have HTTPS enabled with custom domain set).

Verification

CNAME record looks should look something like this:

sub.example.com 60 IN CNAME subexamplecom.herokudns.com

I use the following regex to check the correct CloudFront canonical domain name:

Takeover

Set Project Name and its subdomain. Subdomain does not need to match the domain you are trying to takeover.

In left sidebar, go to General Settings -> Custom Domain.

Set Custom domain to the domain you want to takeover.

Click Save.

Reporting

In the final report, don't forget to mention all the technical parts. You can also specify the simplified process of PoC creation. Regarding the risks, I urge you to read my another post and alternatively link to it in your report. Since subdomain takeover is rather a new attack vector, you should also offer mitigation strategies for the affected party.

Hopefully, this post provides a good view into inner workings of cloud providers with custom domain names. Many other cloud services (one found here) can be used for PoC creation if CNAME record point to them. The process should be similar to one of the services explained above.

You should bookmark this page and come back during actual PoC creation.

How to find vulnerable CNAME records and more stuff related to subdomain takeover will be described in the future posts. Follow me on Twitter to get it first.