← All articles
Threat Intelligence 7 min read

The Anatomy of a Cloud Breach: What Attackers Do in the First 24 Hours

A detailed timeline of how attackers move through AWS environments after initial credential theft — from sts:GetCallerIdentity recon to S3 exfiltration — and what defenders can do at each stage.

CloudDefender Team ·

When IAM credentials are stolen, most organizations don’t realize it for days — or weeks. The attacker, meanwhile, moves methodically through your environment in the first 24 hours, following a well-worn playbook that security teams can learn to recognize and disrupt. Understanding that playbook, stage by stage, is the first step to building detection that actually works.

Hour 0Initial AccessGetCallerIdentityHour 2DiscoveryListRoles / ListBucketsHour 6Lateral Movementsts:AssumeRoleHour 12Exfiltrations3:GetObject (bulk)Hour 24PersistenceNew IAM users / keys
A typical cloud breach unfolds across five stages in the first 24 hours. Each stage has distinct CloudTrail signals defenders can monitor.

Hour 0: Initial Access — The First API Call

Stolen IAM credentials arrive through one of three primary vectors: phishing campaigns targeting developers who receive fake AWS console login pages, secrets accidentally committed to public GitHub repositories (a shockingly common occurrence — GitHub’s own secret scanning has found millions of AWS keys), or exposed .env files in misconfigured web servers or Docker Hub images.

Once an attacker has a working AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY, the very first API call they make is almost universally sts:GetCallerIdentity. This call requires no permissions whatsoever — any valid credential can make it — and it returns the account ID, IAM user ARN, and user ID. It is the attacker’s way of asking “whose keys did I just get, and what account do they belong to?”

This is MITRE ATT&CK technique T1078 (Valid Accounts). The detection signal is precise: a GetCallerIdentity call from an IP address that has never previously called AWS APIs for that identity, or from a UserAgent string that doesn’t match the organization’s known tooling. If your developers use the AWS CLI, an aws-sdk-go UserAgent making this call should raise an alert immediately. Every SIEM ingesting CloudTrail should have this rule firing on day one.

Hour 2: Discovery — Building a Map of the Environment

With account context established, the attacker shifts to the discovery phase. The goal is to enumerate what resources exist, what permissions the stolen role has, and where the valuable data lives. This manifests as a burst of read-only enumeration API calls: iam:ListUsers, iam:ListRoles, iam:ListPolicies, iam:GetPolicyVersion, ec2:DescribeInstances, s3:ListBuckets, rds:DescribeDBInstances, and often organizations:DescribeOrganization to understand whether this is a member account in a larger AWS Organization.

This is T1580 (Cloud Infrastructure Discovery). In isolation, each of these calls appears benign — they’re the same calls your automation tooling makes. The distinguishing signal is the breadth and velocity: a human operator running these interactively will produce dozens of calls in a short window, touching services they haven’t touched before. A CloudTrail-aware SIEM can establish a per-identity baseline of which services are normally called and fire an alert when a principal suddenly starts calling four or five new services within a single hour.

Defenders should also pay close attention to iam:GetPolicyVersion calls on managed policies, particularly on policies attached to high-privilege roles. This is the attacker reading the policy document to understand what permissions they could escalate to.

Hour 6: Lateral Movement — Role Chaining to Higher Privilege

Discovery complete, the attacker now looks for a path to higher privilege. In AWS environments, this almost always means sts:AssumeRole. The attacker uses the iam:ListRoles output to identify roles with sts:AssumeRole in their trust policy that trusts the current principal (or *), particularly any role with AdministratorAccess or broad S3/RDS permissions.

This is T1548 (Abuse Elevation Control Mechanism). The insidious aspect of role chaining is that each AssumeRole call appears in CloudTrail under the assumed role’s identity, not the original stolen credential. A sequence might look like: user dev-ci assumes role deployment-role, which then assumes role data-access-role. CloudTrail will show the s3:GetObject calls under the data-access-role ARN, which is a valid principal that security teams may not immediately associate with the compromised dev-ci key.

Defenders must search CloudTrail for AssumeRole events where the sourceIdentity or userIdentity.principalId contains unexpected chaining patterns. AWS CloudTrail records the full chain in the sessionContext field. Alert on any role assuming a second role if that pattern doesn’t appear in your automation baselines.

Hour 12: Exfiltration — The Silent S3 Drain

With sufficient privileges now in hand, the attacker turns to data collection. S3 buckets identified in the discovery phase are enumerated with s3:ListObjectsV2, and then bulk s3:GetObject calls begin. Hundreds of gigabytes of data can be pulled in minutes over AWS’s own high-bandwidth network.

This is T1530 (Data from Cloud Storage). Here is the critical gap that attackers rely on: S3 data events are not logged by CloudTrail by default. Management events — creating and deleting buckets, changing bucket policies — are logged. But individual GetObject, PutObject, and DeleteObject calls on objects inside buckets are data events and must be explicitly enabled. In the majority of AWS accounts, S3 exfiltration at this stage generates zero CloudTrail log entries.

The immediate defensive action is to enable S3 data event logging on all buckets tagged as sensitive, and to configure S3 server access logging as a parallel signal even where CloudTrail data events aren’t fully enabled. GuardDuty’s S3 protection module provides some coverage through anomaly detection, but it is not a substitute for actual data event logging.

Hour 24: Persistence — Making Sure They Can Come Back

By the 24-hour mark, an attacker with sufficient access will attempt to establish persistence so they survive credential rotation. The techniques are well-known: creating a net-new IAM user with an access key attached to an administrator policy, adding a second access key to an existing human user (harder to notice than a new user), modifying the trust policy on a high-privilege role to trust an external account they control, or deploying a Lambda function with a scheduled trigger that periodically checks in.

Defenders should alert on iam:CreateUser, iam:CreateAccessKey, and any modification to IAM role trust policies (iam:UpdateAssumeRolePolicy) that weren’t initiated through your IaC pipeline. Tools like AWS Config rules can evaluate these in near-real-time. The goal at the 24-hour mark is to have already detected and responded to the Hour 0 signal — if you reach this stage without having caught the breach, the response becomes significantly more complex.

Building Detection That Works Across All Five Stages

The common thread across every stage is CloudTrail. Every API call described in this article generates a CloudTrail management event except for S3 GetObject — which is precisely why enabling data event logging is the highest-priority defensive action most organizations can take. A properly configured SIEM ingesting CloudTrail into a service like Amazon Security Lake, with detection rules for the specific signals at each stage, can reduce mean time to detect from weeks to hours.

The attacker’s playbook is repeatable and detectable. Building detection against it — stage by stage — is how defenders win.

CloudDefender

Defend your cloud. Continuously.

CloudDefender Suite gives security teams continuous posture management, threat detection, and compliance automation across AWS, Azure, and GCP — with zero false-positive fatigue.

Try CloudDefender →