I recently spent some time exploring the issue of CloudFront domain hijacking. This is not a new issue but I think it has gone mostly unnoticed for a few reasons:
- CloudFront's default behavior is not intuitive. Some standard DNS configurations can mislead users into thinking that their vulnerable domains are configured correctly.
- In the past year, misconfigured S3 buckets have been everyone's priority. Other AWS security issues have played second banana.
- Because a misconfigured domain presents an obvious error message, one would assume there is no "low-hanging fruit" for attackers.
There are a couple reports on HackerOne but I'd say that this issue is still relatively unexplored. So I devoted some time to finding the right targets and scripting the testing process. The results are below.
CloudFront is a Content Delivery Network (CDN) provided by Amazon Web Services (AWS). CloudFront users create "distributions" that serve content from specific sources (an S3 bucket, for example).
Each CloudFront distribution has a unique endpoint for users to point their DNS records to (ex. d111111abcdef8.cloudfront.net). All of the domains using a specific distribution need to be listed in the "Alternate Domain Names (CNAMEs)" field in the options for that distribution.
When a CloudFront endpoint receives a request, it does NOT automatically serve content from the corresponding distribution. Instead, CloudFront uses the
HOST header of the request to determine which distribution to use. This means two things:
- If the
HOSTheader does not match a domain in the "Alternate Domain Names (CNAMEs)" field of the intended distribution, the request will fail.
- Any other CloudFront distribution that contains the specific domain in the
HOSTheader will receive the request and respond to it normally.
This is what allows the domains to be hijacked. There are many cases where a CloudFront user fails to list all the necessary domains that might be received in the
- The domain
test.disloops.comis a CNAME record that points to
disloops.comdomain is set up to use a CloudFront distribution.
test.disloops.comwas not added to the "Alternate Domain Names (CNAMEs)" field for the distribution, requests to
- Another user can create a CloudFront distribution and add
test.disloops.comto the "Alternate Domain Names (CNAMEs)" field to hijack the domain.
This means that the unique endpoint that CloudFront binds to a single distribution is effectively meaningless. A request to one specific CloudFront subdomain is not limited to the distribution it is associated with.
Without going into a ton of detail, I wanted to script the process of finding vulnerable domains. I created a Python script called CloudFrunt that:
- Accepts a list of domains
- Runs the domains through dnsrecon to find more domains
- Selects the domains that actually point to CloudFront IP space
- Tests them for configuration issues
- (Optionally) adds them to a new CloudFront distribution
The script itself is here: https://github.com/disloops/cloudfrunt
$ python cloudfrunt.py -l list.txt CloudFrunt v1.0.3 [+] Enumerating DNS entries for google.com [-] No issues found for google.com [+] Enumerating DNS entries for disloops.com [+] Found CloudFront domain --> cdn.disloops.com [+] Found CloudFront domain --> test.disloops.com [-] Potentially misconfigured CloudFront domains: [#] --> test.disloops.com
The next step was to create a list of promising targets. Ultimately, the best solution was just to scrape Robtex for a premium report on every IP in the CloudFront address space.
That yielded 90,500 unique domains attached to about a million IP addresses. So I created an EC2 instance to test from, split up the list and ran CloudFrunt against it in parallel.
After a few days of allowing the script to run, I found that I had added almost 2,000 new domains to CloudFront distributions of my own. Each of them were automatically configured to point to the following page, which has undergone some revisions: CloudFront Hijacking Demo
It was immediately clear that this project had a bigger impact than anticipated. Among the affected domains were some owned by:
- Two distinct US Federal "dot gov" organizations
- Bloomberg Businessweek
- Commonwealth Bank of Australia
- Dow Jones
- Harvard University
- The League of Conservation Voters
- Red Cross
- University of Maryland
- ...and others
(Update 4/23/18: We're up to nine subdomains on five different US "dot gov" sites that have been parked and reported.)
The surprising effectiveness of this exercise meant that the reporting timeline was about to be expedited. I was in touch with an engineer from the AWS CloudFront team to discuss the findings about one week after the first tests began.
- Dec 29, 2017 – Initial investigation
- Jan 2, 2018 – Automated testing begins with increased capacity
- Jan 5, 2018 – Large number of domains have been found and squatted
- Initial contact with AWS CloudFront engineers to discuss findings
- Full incident report is created and submitted to AWS Security team
- Federal domains are reported separately to US-CERT at NCCIC
- AWS engineers are given access to the CloudFrunt scanning tool
- Jan 8, 2018 – Control of the vulnerable domains is transitioned to the AWS CloudFront team
At this point the AWS CloudFront team had created their own distribution to host the vulnerable domains, which points at a landing page of their own creation. As of writing this, many of the domains are still parked there.
A number of discussions with both the AWS Security team and the CloudFront engineers have followed. However, while they accept that the nuances of CloudFront's routing mechanism leave room for improvement, at no time have they decided to treat this issue as a vulnerability.
So after coordination with the appropriate parties at Amazon, this article and the CloudFrunt testing tool itself are being released.
These issues are part of the growing pains of cloud adoption. For CloudFront in particular, most AWS customers with a single distribution can protect themselves by adding a wildcard domain (such as
*.disloops.com) to the "Alternate Domain Names (CNAMEs)" field.
After this year's S3 bucket exposures, Amazon rolled out changes to the console and began alerting users with open buckets. They provided a similar service to users that uploaded their API keys to Github once the issue became pervasive. Depending on the impact of CloudFront domain hijacking, certain safeguards could appear in the near future.
Update 4/25/18: As predicted, AWS has published an article describing some new security measures that have been rolled out to combat this issue: Enhanced Domain Protections for Amazon CloudFront Requests
Please use CloudFrunt to test your own organization for misconfigurations. It is simple to generate a list of domains in every Route 53 hosted zone to test against. Let me know if you have any issues or improvements to suggest!
2 thoughts on “CloudFront Hijacking”
Hi matt, i like your post it helped me understand how cloud front works. But it is no longer possible to register CNAME with domain without corresponding SSL certificate. I tried to register CNAME for distribution from another AWS account and i received error that i need certificate which match this CNAME. So in my opinion your solution will not work any more, or you see any other way to create distribution for domain you dont own?
From AWS Cloud Front change log:
"CloudFront now requires that you use an SSL certificate to verify that you have permission to use an alternate domain name with a distribution. For more information, see Using Alternate Domain Names and HTTPS."
Hi Ondrej – thanks for checking this out. The new AWS requirement for having certificates to match all your "Alternate Domain Name (CNAME)" entries seems like a very effective way to prevent hijack en mass. I have no special insight into a way around that requirement. It looks like hijacking vulnerable domains is now at least as difficult as sourcing a valid SSL certificate for a domain that you don't actually control. If I happen to see anything else on this topic I will be sure to post an update.