This article is part 1 of our AWS Penetration Testing guide.
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.
- Download: The AWS Extender Burp Plugin
- Download: The AWS Extender CLI
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</pre>
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.
Pre-signed URLs
In addition to the access control mechanisms listed above, S3 can allow temporary read/write access to private objects hosted in buckets via pre-signed URLs. Applications that use S3 to host mildly sensitive images such as avatar images are recommended to use pre-signed URLs to ensure images cannot be harvested by other users. Pre-signed URLs typically look like the following:
https://s3.amazonaws.com/{S3_BUCKET}/{path}?AWSAccessKeyId={S3_ACCESS_KEY_ID}&Expires={expire_date}&Signature={signature}
Two checks are performed by the AWS Extender Burp extension:
- Whether or not authentication is enforced for objects referenced in pre-signed URLs.
- Whether the token is valid for an excessive amount of time.
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:
- The extension attempts to list objects hosted in the bucket (READ).
- The extension attempts to upload a “test.txt” file to the bucket (WRITE).
- The extension attempts to retrieve the access control list of the bucket (READ_ACP).
- 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.
Next up, we will discuss EC2 Penetration Testing