Article by Houston Hopkins.
Simple Route53/Cloudfront/S3 Subdomain Takeover
-
Additional Resources
Discover Dangling Domains that point to your cloud assets to prevent subdomain takeover
-
Tools mentioned in this article
dwatch: Fork and stripped down version of a now defunct DomainWatch script from ebelties.
ctfr: Abusing Certificate Transparency logs for getting HTTPS websites subdomains.
Amass: In-depth attack surface mapping and asset discovery.
Utilizing various enumeration techniques for recon and enumeration, an attacker can discover orphaned Cloudfront distributions and/or DNS Records that are attempting to serve content from an S3 bucket that no longer exists. There are numerous tools to do this, but I have been using dwatch combined with CTFR.
Essentially you need a list of domains to check. Create a domain list using CTFR or amass or the like, and then utilize a tool like dwatch to test each host to look for a specific error page that contains the text "NoSuchBucket".
<Error>
<Code>NoSuchBucket</Code>
<Message>The specified bucket does not exist</Message>
<BucketName>hackingthe.cloud</BucketName>
<RequestId>68M9C1KTARF9FBYN</RequestId>
<HostId>RpbdvVU9AXidVVI/1zD+WTwYdVI5YMqQNJShmf6zJlztBVyINq8TtqbzWpThdi/LivlOWRVCPVs=</HostId>
</Error>
The simple next step is to go create a bucket with this name in S3.
This alone can be enough to stop the bucket from being taken over by anyone else. However, you may want to place some POC code in an index.html or any html file in the root directory of the bucket file.
<h1> Simple PoC for Subdomain Takeover,</h1>
<button onclick=alert(document.domain)> XSS Alert for PoC </button>
<h2> demo purposes only. </h2>
Root Causes of this issue are typically due to a hygiene related issues where an S3 bucket was deleted while content was still being served by Cloudfront or by a DNS Record CNAME (Route53 or otherwise).
There are other nuanced conditions with Cloudfront, although rare, that can cause the similar takeover susceptibility.
To protect against this type of attack utilize robust hygiene practices:
Always create in this order S3 -> Cloudfront -> DNS
Always Sunset/Delete in this order DNS -> Cloudfront-> S3
Likewise, if you are testing, and something doesn't work, dont forget to clean up!
I highly recommend looking at OWASP's domain-protect as a framework for detection and event driven mitigation.