AWS Penetration Testing Part 1 – S3 Buckets

Arrow

Penetration Testing AWS Services

AWS Penetration Testing Part 1.
S3 Buckets

Amazon Web Services (AWS) provides some of the most powerful and robust infrastructure for modern web applications. As with all new functionality on the web, new security considerations inevitably arise. For penetration testers, a number of AWS services can pose obscure challenges at times.

In this series of blog posts, we will discuss AWS services in detail, common vulnerabilities and misconfigurations associated with them, and how to conduct sufficient security tests for each service with the aid of automated tools. This article is intended to be used by penetration testers with our AWS BurpSuite extension to easily assess the security of AWS S3 buckets.

We’ve released our BurpSuite plugin AWS Extender which can identify and assess buckets discovered from proxy traffic. It also has been extended to identify identity pools, and Google Cloud and Microsoft Azure services as well.

Amazon Simple Storage Service (S3)

Launched in March 2006 and currently hosting trillions of objects, Amazon S3 is an extremely popular object storage service that provides scalable storage infrastructure. And despite the possibility of hosting static websites, S3 by itself does not support code execution or any programmatic behavior. It only provides storage through the REST, SOAP, and BitTorrent web interfaces to read, upload, and delete static files.

Amazon provides different mechanisms of access control for S3 buckets. That includes access control lists (ACLs), bucket policies, as well as IAM policies. By default, an S3 bucket is assigned a default ACL upon creation that grants the bucket owner full control over the bucket.

S3 Penetration Testing Basics

There’s a few key concepts that any web application penetration tester should be aware of:

  • All S3 buckets share a global naming scheme. Bucket enumeration is not avoidable.
  • All S3 buckets have a DNS entry: [bucketname].s3.amazonaws.com
  • It’s generally easiest to access a bucket over it’s HTTP interface (https://[bucketname].s3.amazonaws.com) or to use the more powerful AWS CLI:
    apt-get install awscli
    aws s3 ls s3://mybucket

S3 Common Vulnerabilities

If you’re new to AWS or S3, there are a few common vulnerabilities you should be aware of:

  • 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.

Access Control Lists (ACLs)

S3 access control lists can be applied at the bucket level as well as at the object level. They generally support the following set of permissions:

  • READ
    At the bucket level, this allows the grantee to list the objects in a bucket. At the object level, this allows the grantee to read the contents as well as the metadata of an object.
  • WRITE
    At the bucket level, this allows the grantee to create, overwrite, and delete objects in a bucket.
  • READ_ACP
    At the bucket level, this allows the grantee to read the bucket’s access control list. At the object level, this allows the grantee to read the object’s access control list.
  • WRITE_ACP
    At the bucket level, this allows the grantee to set an ACL for a bucket. At the object level, this allows the grantee to set an ACL for an object.
  • FULL_CONTROL
    At the bucket level, this is equivalent to granting the “READ”, “WRITE”, “READ_ACP”, and “WRITE_ACP” permissions to a grantee. At the object level, this is equivalent to granting the “READ”, “READ_ACP”, and “WRITE_ACP” permissions to a grantee.

A grantee can be an individual AWS user referenced by his canonical user ID or email address or one of the following predefined groups:

  • The Authenticated Users Group
    Represents all AWS users and is referenced by the URI “http://acs.amazonaws.com/groups/global/AuthenticatedUsers“.
  • The All Users Group
    Represents all users (including anonymous ones) and is referenced by the URI “http://acs.amazonaws.com/groups/global/AllUsers”.
  • The Log Delivery Group
    Relevant only for access logging and is referenced by the URI “http://acs.amazonaws.com/groups/s3/LogDelivery”.

The following is a sample ACL:

<?xml version="1.0" encoding="UTF-8"?>
<AccessControlPolicy xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
  <Owner>
    <ID>*** Owner-Canonical-User-ID ***</ID>
    <DisplayName>owner-display-name</DisplayName>
  </Owner>
  <AccessControlList>
    <Grant>
      <Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
               xsi:type="Canonical User">
        <ID>*** Owner-Canonical-User-ID ***</ID>
        <DisplayName>display-name</DisplayName>
      </Grantee>
      <Permission>FULL_CONTROL</Permission>
    </Grant>
  </AccessControlList>
</AccessControlPolicy> 

All of the aforementioned permissions are currently covered by the AWS Extender Burp extension. Namely, the following tests are performed once an S3 bucket is identified:

  1. The extension attempts to list objects hosted in the bucket (READ).
  2. The extension attempts to upload a “test.txt” file to the bucket (WRITE).
  3. The extension attempts to retrieve the access control list of the bucket (READ_ACP).
  4. The extension attempts to set the access control list of the bucket (WRITE_ACP) without actually changing it.

Note: Similar tests are conducted for every identified S3 object.

Bucket Policies

Using a bucket policy, a bucket owner can specify what a principal can perform on a specific resource. Where a principal can be any AWS user/group or all users including anonymous ones, an action can be any predefined permission supported by bucket policies, and a resource can be the entire bucket or a specific object. The following is a sample bucket policy expressed in the JSON format:

{
    "Version":"2012-10-17",
    "Statement": [
        {
            "Effect":"Allow",
            "Principal": "*",
            "Action":["s3:GetObject"],
            "Resource":["arn:aws:s3:::examplebucket/*"]
        }
    ]
}

This policy allows the “s3:GetObject” action on the resource “arn:aws:s3:::examplebucket/*” for a wildcard principal “*”. This is effectively equivalent to granting the “READ” permission to the All Users group on the “examplebucket” S3 bucket using an access control list (ACL).

The following permissions are currently covered by the AWS Extender Burp extension:

  • s3:ListBucket
  • s3:ListMultipartUploadParts
  • s3:GetBucketAcl
  • s3:PutBucketAcl
  • s3:PutObject
  • s3:GetBucketNotification
  • s3:PutBucketNotification
  • s3:GetBucketPolicy
  • s3:PutBucketPolicy
  • s3:GetBucketTagging
  • s3:PutBucketTagging
  • s3:GetBucketWebsite
  • s3:PutBucketWebsite
  • s3:GetBucketCORS
  • s3:PutBucketCORS
  • s3:GetLifecycleConfiguration
  • s3:PutLifecycleConfiguration
  • s3:PutBucketLogging

Part 2 of the AWS series will cover more on S3 permissions including IAM and access tokens, as well as considerations for EC2, Cognito authentication and more. Read part 2 here.