August 3, 2017AWS S3 tips security
Today was a day for tidiness so I decided to split up some AWS services that I’ve been managing into separate AWS accounts. I do A LOT of proof of concepts and didn’t want those services to go down in the event that my AWS account gets locked out—for whatever reason. While I have of course read the AWS Acceptable Use Policy and would never intentionally violate the terms, I’m also aware that AWS can shut my account down whenever they feel like it so why take the chance right?
I’ve setup and secured hundreds of AWS accounts over the years and this time was no different. As a matter of fact, I setup a new one a few days ago and was able to use it immediately. Typically you get three emails after creating your new account and you are ready to roll when you receive the Your AWS Account is Ready - Get Started Now email:
So I got my new AWS account setup and as any good AWS engineer would do, I setup all of the contact info, alternate contacts, and security challenge questions. I then promptly deleted my website hosted S3 buckets so that I could recreate them in the new account. But when I tried opening up CloudFormation to deploy my buckets, I got the following message:
Obviously this is a security measure to prevent abuse however, I’d never seen this before and it kind of caught me with my pants down. I was planning on doing a quick move of static web hosted S3 buckets to the new account. Unfortunately, you can’t actually move an S3 bucket to another AWS account like you can with Route 53 hosted domains. You have to delete the bucket—which I did—and then recreate it in the target AWS account—which I couldn’t.
This process is a bit worrisome because static website hosted S3 buckets are a little different—if you want to use them for a website you have to use the actual DNS name of your website for the bucket name……and if someone creates that bucket name before you do, you are hosed. In case you missed it, AWS does mention this “small” detail in their online documentation:
If you want to continue to use the same bucket name, don’t delete the bucket. We recommend that you empty the bucket and keep it. After a bucket is deleted, the name becomes available to reuse, but the name might not be available for you to reuse for various reasons. For example, it might take some time before the name can be reused and some other account could create a bucket with that name before you do.
It seems that this design could be abused—S3 bucket squatting is the first thing to comes to mind. I don’t think S3 bucket squatting is a thing yet but I really hope AWS addresses this in the near future as it’s too easy to exploit some neglected
vulnerabilities design flaws. While having someone intentionally or unintentionally grab an S3 bucket named with your domain URL would be annoying as hell, it’s not a huge vulnerability per se. To most its probably akin to not being able to register the Twitter or Reddit name that you want to use. However, unsecured S3 buckets have been in the news quite often lately—here are two big ones:
- May 2017 - Top Defense Contractor Left Sensitive Pentagon Files on Amazon Server With No Password
- June 2017 - GOP Data Firm Accidentally Leaks Personal Details of Nearly 200 Million American Voters
Unsecured S3 buckets are definitely an issue but being able to setup a website hosted S3 bucket using someone else’s domain name could be an issue. I quickly and easily found one example of this by testing my theory on 50 of the Alexa’s The top 500 sites on the web.
On my laptop I decided to try scraping the first 50 URLs and check to see if an S3 bucket exists or not. Here is the script I made:
for sites in `curl -Ss http://www.alexa.com/topsites | grep -Eo '/siteinfo/(.*)">' | sed 's/\/siteinfo\///;s/">//'`; \ do \ echo $sites && echo -e '\n' && \ aws s3 ls s3://$sites 2> >(grep -C 2 "The specified bucket does not exist"); \ done
Is this script sexy? Nope. But could I exploit the S3 API to quickly find and register an S3 bucket name that hasn’t been registered yet by a large company? Absolutely!
Of the first 50 domains listed on Alexa’s top sites on August 5th, 2017 there was one that did not have an S3 bucket created—here is what my script spits out when this happens:
lXXX.XXXXl.com An error occurred (NoSuchBucket) when calling the ListObjects operation: The specified bucket does not exist
Here is the actual screenshot if you think I’m full of cow poo:
So what is the problem here? Maybe the owner of that domain knows that they will never, ever use AWS S3? Perhaps, but when you are a huge company with millions—or even billions—of users your threat model can become vast. Let’s explore this further…
It’s perfectly legal for me to register any AWS S3 bucket that I want so I registered an S3 bucket using the DNS name of the website I found:
VirtualJJ:Downloads virtualjj$ aws s3 mb s3://lXXX.XXXXl.com make_bucket: lXXX.XXXXl.com
We can configure website hosting from the AWS CLI as documented here but I’ll do it from the console to more easily illustrate my point:
Does that endpoint look malicious to you? AWS is of course a reputable company and I wouldn’t fault most for not realizing that the link could be malicious. Chances are that AWS would probably shutdown the bucket or even the AWS account if malware is being served but detection could be too little too late. Just look at something nasty like WannaCry, the ransomeware attack that crippled even hospitals recently. A URL generally only has to look somewhat legitimate to be used maliciously and I think this is one of those cases.
So how could AWS mitigate this? In order to activate a static website hosting s3 bucket perhaps AWS could require proof of domain name ownership. This would reduce the amount of domain name squatting on S3 buckets as well as mitigate the threat of web hosting enabled buckets used for nefarious purposes. Fortunately for me, it didn’t take a full 24 hours for AWS to activate my new account—it took a little over seven hours—and I was able to recreate my static website hosting S3 buckets before anyone else registered them.
If you liked this post please click Follow @virtualjj and say hello!