Cloud storage misconfigurations remain one of the most common ways organizations expose sensitive data. Attackers run automated scans to find publicly accessible S3 buckets, and once inside, they look for credentials that unlock deeper access to the environment. The challenge for defenders is separating noisy baseline behavior from genuine compromise attempts in the logs these activities generate.
A recent threat hunting guide from BinaryDefense walks through a controlled attack simulation targeting a misconfigured S3 bucket, then shows exactly which CloudTrail API calls the activity produces. The exercise demonstrates how security teams can build targeted detection logic in Sentinel using KQL queries to surface suspicious S3 interactions before data leaves the bucket.
What the Attack Looked Like
The simulation ran in a lab environment replicating a small organization with users, roles, groups, and policies. The target was an S3 bucket configured with overly permissive access—open to the public, matching the T1530 MITRE ATT&CK technique for data from cloud storage.
Before launching the attack, the operator installed the AWS CLI and configured it with a default profile. The offensive toolkit chosen was cloud_enum, an open-source multi-cloud reconnaissance tool that probes for public resources across AWS, Azure, and Google Cloud.
The attack proceeded in three stages. First, keyword scanning using the target organization's name, website, and product names identified exposed buckets. Second, the operator listed the discovered bucket contents using standard AWS CLI commands. Third, a bulk synchronization pulled all available data from the bucket to local storage.
The bucket contained a file named "Sensitive Items." Inside were an access key ID and secret access key belonging to an IAM user called "AWSCloudAdmin"—a credential an attacker could immediately use to establish a foothold in the AWS environment through the command line interface.
Reading the Trail: KQL Queries That Surface the Activity
CloudTrail captures every API call made in an AWS account, but raw logs are noisy. The BinaryDefense walkthrough shows how layered KQL queries narrow the signal.
The first query looks for ListAccessPoints events—a baseline S3 enumeration call. The query projects time generated, event name, username, request parameters, source IP address, and user agent, then isolates distinct values. This reveals the external IP address performing reconnaissance: 23.241.27.253.
A second query filters directly on that IP, sorting events chronologically to map the attacker's behavior over time. The result shows the IP exercised the GetObject API call, retrieving content from the bucket rather than merely listing it.
A third query targets user agent strings containing "Linux"—a common indicator of AWS CLI usage, since the command-line tools report a Linux-based user agent by default. This helps distinguish legitimate scripted access from human-driven console operations.
The most specific query combines the bucket name with the suspicious IP, effectively narrowing to the exact interaction sequence that constitutes the breach. Each query builds on the previous, allowing analysts to move from anomaly to confirmation without drowning in irrelevant events.
Amazon GuardDuty automatically classified the GetObject call from the external IP as "PenTest: S3 / KaliLinux," flagging the operation as consistent with an intrusion testing tool. GuardDuty did not require custom rules to surface this, though custom logic would be needed to catch variations or lower-profile reconnaissance.
Why This Matters
Two things stand out from this exercise. First, the attack succeeded because the S3 bucket was publicly accessible. This is a configuration error, not a software vulnerability—there is no patch to apply, only a policy to correct. Second, the AWS CLI was the attacker's preferred interface. Using the command line to interact with S3 rather than the management console is perfectly normal for scripts and deployments, but it is uncommon for most end-user workflows. That gap between expected and actual behavior is a detection opportunity.
The KQL queries described here translate well to other environments. ListAccessPoints appears whenever anyone enumerates bucket access points. GetObject from an unexpected IP and user agent combination is a high-confidence indicator of unauthorized access. The queries are not specific to Sentinel either; the same logic applies to any platform consuming CloudTrail logs.
GuardDuty catches obvious cases, but it operates on a fixed detection library. Organizations facing targeted campaigns or novel tooling need their own detection logic layered on top. The queries demonstrated here provide a starting framework, but teams should tune thresholds and add context—such as geography, time-of-day, and account history—to reduce false positives.
Who Should Care
| Role | Primary Concern | Relevant Queries |
|---|---|---|
| SOC Analysts | Distinguishing attacker activity from legitimate automation | UserAgent filtering; IP-to-bucket correlation |
| Cloud Engineers | Preventing misconfiguration at the source | N/A (policy review, not log analysis) |
| Incident Responders | Confirming breach scope and timeline | Chronological IP activity; credential access indicators |
| Compliance Teams | Demonstrating detective controls to auditors | Multi-layered query approach; documented detection logic |
Practical Example
Say your organization runs automated backups to an S3 bucket that multiple services access throughout the day. Baseline CloudTrail volume is substantial, so a simple GetObject alert would generate noise. Instead, create a watchlist of known service accounts and their associated IPs. Any GetObject call from an IP not on that list, or using a Linux user agent when your services run Windows-based hosts, warrants investigation. This layered approach catches the attacker in the simulation while allowing normal operations to continue without interruption.
Bottom Line
S3 bucket misconfigurations remain an active and preventable attack vector. Automated tooling finds exposed buckets, and once an attacker obtains credentials from inside a bucket, the incident escalates from data exposure to full environment compromise. CloudTrail logs capture the evidence, but only if detection logic knows what to look for. The KQL queries demonstrated here—tracking enumeration patterns, CLI-based access, and unusual IP-to-bucket mappings—give security teams a practical framework for hunting this activity in their own environments. GuardDuty provides a baseline, but custom detection rules tuned to your specific workload patterns will catch what generic signatures miss.
Key takeaways
- Publicly accessible S3 buckets with sensitive data are discovered by automated reconnaissance tools like cloud_enum
- AWS CLI usage produces distinct user agent strings and API call patterns that differ from normal console operations, making them useful detection signals
- Layered KQL queries—starting broad and narrowing to specific IPs, buckets, and API calls—allow analysts to confirm suspicious activity without excessive noise
- GuardDuty catches obvious Kali Linux-style attacks but cannot replace custom detection logic for targeted or novel campaigns
- Remediation requires correcting bucket policies rather than waiting for a patch; monitoring must bridge the gap between configuration and compromise
Frequently asked questions
How did the simulated attack discover the vulnerable S3 bucket?
The attacker used cloud_enum, an open-source multi-cloud reconnaissance tool, to scan for publicly accessible resources using keywords matching the target organization's name and products. The tool identified an incorrectly configured S3 bucket.
What sensitive data did the attacker extract from the bucket?
Inside the bucket was a file named "Sensitive Items" that contained an IAM access key ID and secret access key for a user called "AWSCloudAdmin." These credentials would allow the attacker to authenticate to the AWS environment directly.
Which CloudTrail API calls indicate an S3 bucket enumeration or data extraction attempt?
ListAccessPoints signals bucket enumeration. GetObject indicates data retrieval from a bucket. When combined with an unexpected source IP and a Linux-based user agent (characteristic of AWS CLI usage), these events strongly suggest unauthorized access rather than legitimate administrative activity.
Can GuardDuty detect S3 bucket attacks automatically?
GuardDuty flagged the simulated GetObject call as "PenTest: S3 / KaliLinux" without custom rules, but GuardDuty operates from a fixed detection library. Targeted attacks using custom tooling or slower reconnaissance may evade these signatures, making supplemental detection logic necessary for thorough coverage.
What is the most effective way to prevent S3 bucket attacks?
Eliminate public access to S3 buckets that contain sensitive data or credentials. Use bucket policies and IAM policies to restrict access to known, authorized principals only. Regularly audit bucket configurations and monitor CloudTrail logs for the enumeration and access patterns described here.