LTR101: My First CloudFront Domain Takeover/Hijack

LTR101: My First CloudFront Domain Takeover/Hijack

Update 2021/2022: This technique no longer works for Subdomain Hijacking as Amazon have patched it. The only way to hijack the subdomain is if you have control over DNS for the domain and that requires deeper compromise.

Sub Domain Hijack Issue

Hijack/takeover attacks can happen when a company creates a DNS entry that points to a third party service(CNAME Record), however, forget about the third party application leaving it vulnerable to be hijacked by another party. In this case, the other party would be an attacker, by doing so they can deface or redirect users to another location. This attack is practically non-traceable.

In this scenario, I was able to take over a sub-domain of a company that was pointing to a non-existent CloudFront(CF) domain; luckily there are some issues with AWS meaning anyone can claim an expired or non-used CF domain.

CloudFront Explained


Amazon CloudFront is a web service that works as a content delivery network(CDN), it speeds up distribution of static and dynamic web content, such as HTML, javascript, CSS, PHP, and image files. Many sites and organisations use it as a service for distributing their content faster on servers local to users. If you want to find out more about the service have a read of Amazon's developer documentation here.

Discovery

My first sub-domain hijack was discovered while doing usual recon, the usual subdomain brute-forcing, then a quick nmap to look for web apps on high ports followed by a new check I've only recently started doing: sub-domain hijack(also called a take-over) checking.

The easiest way I've found to check for take-overs is to query a list of domains and check for any that are either 1) attached to a third party domain or destination via the use of a cname record or 2) return a 404 not found error.

In this case, I came across a domain that resolved to a CloudFront domain which gave the following error: "Error the request could not be satisfied, generated by CloudFront (CloudFront)" which looks similar to that shown below:

This error is a relatively common and standard error when identifying CF domains that might not be used anymore. A quick verification can be carried out to find out what subdomain is linked to the instance by using dig.

Dig Usage

In the example below doing a simple dig against the target domain will return output similar to shown:

# dig example.com

; <<>> DiG 9.10.3-P4-Debian <<>> example.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 25169
;; flags: qr rd ra; QUERY: 1, ANSWER: 9, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;example.com. IN      A

;; ANSWER SECTION:
example.com. 3599 IN  CNAME   example.cloudfront.net.
example.cloudfront.net. 59 IN    A       x.x.x.238
example.cloudfront.net. 59 IN    A       x.x.x.251
example.cloudfront.net. 59 IN    A       x.x.x.127
example.cloudfront.net. 59 IN    A       x.x.x.253
example.cloudfront.net. 59 IN    A       x.x.x.6
example.cloudfront.net. 59 IN    A       x.x.x.114
example.cloudfront.net. 59 IN    A       x.x.x.22
example.cloudfront.net. 59 IN    A       x.x.x.106

;; Query time: 144 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Tue Oct 10 12:55:44 EDT 2017
;; MSG SIZE  rcvd: 229

From the output, the essential information we are interested in is the answer section and specifically if there is a CNAME present. An easy way of identifying this would be to run dig with grep:

# dig example.com  | grep CNAME
example.com. 3027 IN  CNAME   example.cloudfront.net.

The CNAME value is our target for takeover, the next sections explain what CloudFront is, how it works & how to claim a non-used CF domain.

How to Claim CloudFront & Setup

Now, what if you find yourself in the position where you have a domain that is pointing to a non-existent CF domain? Well if it's a bug bounty or pentest & in scope it might be worth trying to take it over. Here are the steps and requirements to take over a CF domain.

AWS Side

The first thing you'll want to do is sign up for an Amazon web services(AWS) account, this is free to do and worth it for these sorts of things. Once you've got an account.

Head over to the CloudFront signup, and sign up for free. Then select create a distribution & select web as the delivery method as shown in the two screenshots below.


Once you click getting started you will be presented with a screen very similar to this one:

The first red box is where you put the CF domain you want to claim. Once you've done this scroll down to the "Distribution Settings" area:

In the "Alternate Domain Names(CNAMEs)" section, input the sub-domain which you want to take over, identified from the discovery phase detailed above. Leave the rest as default then click create. Once you've created your distribution, it should look something like this:

The next step is to point the newly created CF domain at your content as a source. This is done by adding an origin, simply select the distribution then navigate to the origins tab and select create origin, don't worry if there's one there already, you can choose to edit this too.

Input either an S3 bucket or web domain that you own into "Origin Domain Name" give it an ID, this can be whatever you want, leave everything else as default then select create. If successful you should now have an origin with your custom domain:

Finally navigate to the home page for your CF, if all has gone through successfully you should see your newly created distribution in the in progress state. This means that CF is loading your content into its system and is slowly deploying the take over content, note this could take an hour or so to show up on the target domain however you can check by browsing to the CF domain directly.

Where the first URL is the CF domain you've claimed, the second URL is your server or S3 bucket & the last link is the domain or sub-domain that you're taking over.

Your Domain or Content

Once you've got the basic setup done on the CF side, next is the step of creating your take over page. This can effectively be anything you want to host on either S3 bucket or your own web server. Typically I'll use the following code:

<!DOCTYPE html>
<html>
<head>
    <title>Sub-domain Takeover ZephrFish</title>
</head>
<body>
    <h1>Sub-domain Hijack/Takeover Proof of Concept by INSERT HANDLE HERE</h1>
    <script>
    document.write("Sub-domain Hijack/Takeover Proof of Concept " + document.domain + " by ZephrFish")
    </script>
</body>
</html>

It is a static page with a little JavaScript to highlight the domain that's being taken over/hijacked. Now if you don't own a VPS or server, not to worry this is where AWS is very useful, you can create an S3 bucket. Just navigate to AWS console, and select S3 then create a bucket, set it to the public and upload an index.html to it, then set the S3 bucket as the origin within CF, and you should be golden for sub takeover.

Other Services

This post has covered off how to take over a CloudFront sub-domain; however, there are many other 3rd party services that can be hijacked too.

Further Reading

For more information surrounding sub-domain takeovers and hijacks check out the following links which contain beneficial information & write-ups:

A couple of noteworthy take-overs that are publicly viewable are from various hackerone reports: