Detecting S3 Bucket Attack
By Sean Fernandez | Threat Researcher | Binary Defense
In part 2 of the blog series, Threat Hunting AWS CloudTrail with Sentinel, we simulated an attack on a misconfigured S3 bucket. The attacks were deployed on a test AWS environment that emulated a small organization with a set of users, roles, groups, and policies. We utilized Sentinel to gather raw event information and to analyze the logs produced during the simulation.
We’ll walk through the steps to conduct the simulation, how to analyze the logs uncovered by Sentinel and most importantly the way we can detect threat activity with KQL queries, which can be applied in your own threat hunts.
Exploits a Publicly Accessible Misconfigured S3 Bucket – T1530
In this scenario, the threat actor targets the test AWS environment using an open-source toolkit that scans for public resources. The scan locates a misconfigured S3 bucket with open permissions and reveals sensitive data.
Before initiating the attack, the AWS CLI must be installed and configured with the AWS default profile using:
~$ aws configure
For this attack, we leveraged the open-source tool, cloud_enum.
The cloud_enum tool is a multi-cloud OSINT tool that enumerates public resources in AWS, Azure and Google Cloud.
// keyword search to locate public facing buckets for a target org ~$ ./cloud_enum.py -k <target org name> -k <target org’s website> -k <product keyword>
// lists out the contents in the s3 bucket ~$ sudo aws s3 ls s3://<bucket name>
// pulls the data from the directory ~$ sudo aws s3 sync s3://<bucket name>
Navigated to the folder with the S3 contents and located a file named “Sensitive items”
Printed the contents of the “Sensitive items”
Discovered an Access Key ID and Secret Key for the IAM “AWSCloudAdmin” user.
After the attack was successfully executed, the threat actor obtains credentials to gain an initial foothold onto the AWS environment with stolen keys via the AWS CLI.
Hunting CloudTrail Logs in Sentinel with KQL Queries
The following is a breakdown of our CloudTrail log analysis and hunting process of the API calls during our simulation.
The CloudTrail logs ingested into Sentinel were first analyzed with basic KQL queries. To further narrow in on the attacks more specific queries were executed.
Hunting for S3 enumeration
Query filters: “ListAccessPoints”
// API returns a list of access points with bucket AWSCloudTrail | where EventName has "ListAccessPoints" | distinct TimeGenerated, EventName, UserIdentityUserName, RequestParameters, SourceIpAddress, UserAgent
The query reveals that “SouceIpAddress” of “188.8.131.52” enumerated the target S3 bucket from the attack. The event “ListAccessPoint” returns a list of the access points currently associated with the specified bucket.
Hunting for actions from a specified IP
Query filters: “SourceIpAddress”
// investigate suspicious IP AWSCloudTrail | where SourceIpAddress == "184.108.40.206" | distinct TimeGenerated, EventName, UserIdentityUserName, RequestParameters, SourceIpAddress, UserAgent | sort by TimeGenerated
The result reveals that the IP under investigation invoked the API call action “GetObject”
Hunting for specific user activity
Query filters: “UserAgent”
// Specific useragent activity AWSCloudTrail | where UserAgent has "Linux" | sort by TimeGenerated
Hunting for S3 bucket exfiltration
Query filters: “GetObject”
AWSCloudTrail | where RequestParameters has "GetObject" | distinct TimeGenerated, EventName, UserIdentityUserName, RequestParameters, SourceIpAddress, UserAgent | sort by TimeGenerated asc
The query reveled that the IP address invoked the “GetObject” command.
Hunting for specific API activity
Query filters: “RequestParameters” and “SourceIpAddress”
AWSCloudTrail | where RequestParameters has "demo-jacko-s3-bucket-2021" | where SourceIpAddress == "220.127.116.11" | distinct TimeGenerated, EventName, UserIdentityUserName, RequestParameters, SourceIpAddress, UserAgent | sort by TimeGenerated asc
Pulling together our investigative results, we narrow down our query to search for activities from the specified IP and S3.
Conducting attack simulations in a lab environment is a valuable practice for defenders to prioritize alerts for cloud-specific events. In this scenario, we analyzed the logs that were generated from a misconfigured Amazon S3 attack. Some queries were based on the findings from Amazon GuardDuty, which categorized the event as a PenTest:S3/KaliLinux. GuardDuty determined that the API GetObject was invoked from a remote host potentially running the Kali Linux penetration testing tool.
In order to effectively monitor for anomalous S3 bucket activity, SOC Analysts can alert on the events we investigated and build custom detections for your environment.
The API actions logged in CloudTrail include:
- ListAccessPoint: returns a list of access points associated with a specified bucket, which could be an enumeration tactic.
- GetObject: retrieves objects from Amazon S3. A threat actor is more likely to interact with the AWS environment with the AWS CLI versus the management console. Extracting the contents of an S3 via the AWS CLI, may not be common practice for most AWS environments.
Additional anomalous indictors to consider can include accounts created from different IPs, different city/state, country from admin(s) and abnormal user hours. Detections can also monitor the threshold for allotted admins on an account. During the recon stages, threat actors are likely to leverage automated tools that produce a lot of noise within a short period of time. Consider a detection for high ingress connections on ports 80 and 443, which could indicate enumeration scans.
To better establish baselines, security teams should work through incidents and investigations specific to the cloud to build useful metrics. Using these metrics can add context for defining priorities that will help drive down false positives.
In part three of the series, we will look at a series of adversary attacks focusing on persistence with backdoor access to a secondary access key and temporary security credentials.