Amazon Simple Storage Service (Amazon S3)

💡 See Pacu and Prowler.

➡ Vulnerability description for reporting available in VulnDB (GitHub)

BChecks available on GitHub.

S3 Bucket Names

How to find unsecured S3 buckets

http://s3.amazonaws.com/[bucket_name]/
http://[bucket_name].s3.amazonaws.com/

Access the bucket URL in a browser.

  • Private bucket will respond with code “AccessDenied”.
  • Public bucket will list the first 1,000 objects that have been stored.
  • Inexistent bucket will respond with code “NoSuchBucket”.

Find public buckets

💡 Best option is to use Gobuster in s3 mode.

Manually

http://s3.amazonaws.com/<bucketname>

Bucket Finder

Could use Cewl to generate a wordlist first.

git clone https://github.com/digininja/CloudStorageFinder.git
cd CloudStorageFinder
./bucket_finder.rb wl.txt

Burp extension: AWS Security Checks

Prerequisites

Download boto3

cd boto3
pip --proxy http://user:password@proxy.com:8080 install --trusted-host pypi.org --trusted-host files.pythonhosted.org boto3 --target C:\<path to jython>\jython\Lib

Testing

Unauthenticated Bucket Access – As the name implies, an S3 bucket can be configured to allow anonymous users to list, read, and or write to a bucket.
Semi-public Bucket Access – An S3 bucket is configured to allow access to “authenticated users”. This unfortunately means anyone authenticated to AWS. A valid AWS access key and secret is required to test for this condition.
Improper ACL Permissions – The ACL of the bucket has it’s own permissions which are often found to be world readable. This does not necessarily imply a misconfiguration of the bucket itself, however it may reveal which users have what type of access.

Installation & Setup of AWS Client (awscli)

apt install awscli
apt upgrade awscli

See Official Documentation.

# Configure the client
aws configure
AWS Access Key ID: PRESS ENTER
AWS Secret Access Key: PRESS ENTER
Default region name: PRESS ENTER
Default output format: PRESS ENTER

List bucket content

All S3 buckets have a DNS entry: [bucketname].s3.amazonaws.com (or [bucketname].s3-[region].amazonaws.com, to be confirmed). –no-sign-request will not ask for credentials, but you MUST PROVIDE A REGION.

# export http_proxy="http://127.0.0.1:3128"
aws --no-sign-request s3 ls s3://mybucket.s3-us-east-2.amazonaws.com
aws --no-sign-request --region=us-east-2 s3 ls s3://mybucket.s3.amazonaws.com

Try to write in bucket

touch test.txt
aws --no-sign-request s3 cp test.txt s3://<bucketname>/test.txt

Using Curl

curl -X PUT -d 'test' 'http://s3.amazonaws.com/<bucketname>/test.txt'
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>AccessDenied</Code><Message>Access Denied</Message><RequestId>...</RequestId><HostId>...</HostId></Error>