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.
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.
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: 184.108.40.206#53(220.127.116.11) ;; 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.
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.
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>
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.
For more information surrounding sub-domain takeovers and hijacks check out the following links which contain beneficial information & write-ups:
- SSO Bypass & Domain Takeover
- Subdomain take over principles
- AWS Domains Dangling
- Taking over 120k Domains
A couple of noteworthy take-overs that are publicly viewable are from various hackerone reports: