Detection: Detect New Open S3 Buckets over AWS CLI

Description

The following analytic detects the creation of open/public S3 buckets via the AWS CLI. It leverages AWS CloudTrail logs to identify events where a user has set bucket permissions to allow access to "AuthenticatedUsers" or "AllUsers." This activity is significant because open S3 buckets can expose sensitive data to unauthorized users, leading to data breaches. If confirmed malicious, an attacker could gain unauthorized access to potentially sensitive information stored in the S3 bucket, posing a significant security risk.

 1`cloudtrail`
 2eventSource="s3.amazonaws.com"
 3eventName="PutBucketAcl"
 4errorCode=success
 5userAgent IN ("[aws-cli*", "aws-cli*")
 6
 7
 8| rename requestParameters.bucketName AS bucketName
 9         requestParameters.accessControlList.x-amz-grant-read AS grantRead
10         requestParameters.accessControlList.x-amz-grant-read-acp AS grantReadAcp
11         requestParameters.accessControlList.x-amz-grant-write AS grantWrite
12         requestParameters.accessControlList.x-amz-grant-write-acp AS grantWriteAcp
13         requestParameters.accessControlList.x-amz-grant-full-control AS grantFullControl
14         requestParameters.x-amz-acl AS cannedAcl,
15         userIdentity.principalId AS principalId
16         userIdentity.userName AS userName
17         userIdentity.arn AS userArn
18
19
20| eval grantRead=coalesce(grantRead,"-"),
21       grantReadAcp=coalesce(grantReadAcp,"-"),
22       grantWrite=coalesce(grantWrite,"-"),
23       grantWriteAcp=coalesce(grantWriteAcp,"-"),
24       grantFullControl=coalesce(grantFullControl,"-"),
25       cannedAcl=coalesce(cannedAcl,"-"),
26       user=coalesce(userName,userArn)
27
28
29| eval publicGrant = if(
30                        match(grantRead, "(?i)AllUsers
31|AuthenticatedUsers")
32                        OR
33                        match(grantReadAcp, "(?i)AllUsers
34|AuthenticatedUsers")
35                        OR
36                        match(grantWrite, "(?i)AllUsers
37|AuthenticatedUsers")
38                        OR
39                        match(grantWriteAcp, "(?i)AllUsers
40|AuthenticatedUsers")
41                        OR
42                        match(grantFullControl, "(?i)AllUsers
43|AuthenticatedUsers"),
44                        1,
45                        0
46                    )
47
48
49| eval publicCanned = if(cannedAcl IN ("public-read", "public-read-write", "authenticated-read"), 1, 0)
50
51
52| where publicGrant=1 OR publicCanned=1
53
54
55| eval exposure=case(cannedAcl=="public-read-write","public-write", match(grantWrite."".grantWriteAcp."".grantFullControl,"(?i)AllUsers"),"public-write", cannedAcl=="public-read" OR match(grantRead,"(?i)AllUsers"),"public-read", cannedAcl=="authenticated-read" OR match(grantRead,"(?i)AuthenticatedUsers"),"authenticated-read", true(),"custom-grant")
56
57
58| stats count
59        min(_time) AS firstTime
60        max(_time) AS lastTime
61        values(cannedAcl) AS cannedAcl
62        values(grantRead) AS grantRead
63        values(grantReadAcp) AS grantReadAcp
64        values(grantWrite) AS grantWrite
65        values(grantWriteAcp) AS grantWriteAcp
66        values(grantFullControl) AS grantFullControl
67        values(eventName) AS eventName
68
69  BY user principalId userAgent bucketName exposure
70
71
72| `security_content_ctime(firstTime)`
73
74| `security_content_ctime(lastTime)`
75
76| `detect_new_open_s3_buckets_over_aws_cli_filter`

Data Source

Name Platform Sourcetype Source
AWS CloudTrail AWS icon AWS 'aws:cloudtrail' 'aws_cloudtrail'

Macros Used

Name Value
security_content_ctime convert timeformat="%Y-%m-%dT%H:%M:%S" ctime($field$)
detect_new_open_s3_buckets_over_aws_cli_filter search *
detect_new_open_s3_buckets_over_aws_cli_filter is an empty macro by default. It allows the user to filter out any results (false positives) without editing the SPL.

Annotations

- MITRE ATT&CK
+ Kill Chain Phases
+ NIST
+ CIS
- Threat Actors
ID Technique Tactic
T1530 Data from Cloud Storage Collection
Exploitation
DE.CM
CIS 10

Default Configuration

This detection is configured by default in Splunk Enterprise Security to run with the following settings:

Setting Value
Disabled true
Cron Schedule 0 * * * *
Earliest Time -70m@m
Latest Time -10m@m
Schedule Window auto
Creates Finding (Notable) Yes
Rule Title %name%
Rule Description %description%
Notable Event Fields user, dest
Creates Intermediate Finding (Risk Event) No
TTP detections generate a Finding (Notable) and may generate Intermediate Findings (Risk Events) for associated entities.

Implementation

The Splunk AWS Add-on and Splunk App for AWS is required to utilize this data. The search requires AWS Cloudtrail logs.

Known False Positives

It is possible that an AWS admin has legitimately created a public bucket for a specific purpose. AWS strongly advises against granting full control to the "All Users" group. Investigate and apply the necessary filters as needed.

Associated Analytic Story

Finding

Title Entity Field Entity Type Risk Score
User [$user$] has created an open/public S3 Bucket [$bucketName$] using AWS CLI with the following permissions - [$grantRead$] [$grantReadAcp$] [$grantWrite$] [$grantWriteAcp$] [$grantFullControl$] [$cannedAcl$] user user 50

Threat Objects

Field Type
bucketName bucket_name

References

Detection Testing

Test Type Status Dataset Source Sourcetype
Validation ✅ Passing N/A N/A N/A
Unit ✅ Passing Dataset aws_cloudtrail aws:cloudtrail
Integration ✅ Passing Dataset aws_cloudtrail aws:cloudtrail

Replay any dataset to Splunk Enterprise by using our replay.py tool or the UI. Alternatively you can replay a dataset into a Splunk Attack Range


Source: GitHub |

Version: 11