AWS privilege escalation is the set of techniques an attacker uses to turn a low-privileged foothold in an Amazon Web Services account into higher, often administrative, access. In almost every case it is a chain of overly broad IAM permissions and deploy-as-a-role paths, not a software exploit, which is why identity and configuration, not patching, are the real perimeter in the cloud. This guide covers what AWS privilege escalation is, the dangerous IAM permissions and combinations behind it, the main escalation paths, a real-world incident, how we test for it, and how to defend against it.
What is AWS privilege escalation?
Privilege escalation is the act of gaining permissions beyond those you were granted. In AWS, the currency is IAM: users, roles, groups, and the policies attached to them. An attacker who lands in an account with a limited set of permissions looks for an action, or a combination of actions, that lets them grant themselves more access, assume a more powerful role, or run code as a privileged service identity. The goal is almost always the same, reach a principal that can perform any action on any resource, and the account is then fully compromised. Because these paths are built from legitimate API calls, they succeed quietly and rarely trip a traditional alarm.
How attackers escalate in AWS
AWS privilege escalation is a chain, and it usually starts from one of two places: a set of IAM credentials recovered during an engagement, or code execution on a compute resource that carries an IAM role. From there the attacker enumerates what the current identity can do, looks for a dangerous permission or a role they can reach, and uses it to widen access one step at a time until they hold administrator. The mental model that matters is that IAM grants are additive and that the trust between identities is only as strong as the weakest policy, so a single over-scoped permission anywhere in the account can become the whole chain. We teach and test this end to end in the ACRTP bootcamp, from the first recovered key to full account compromise.
Dangerous IAM permissions and combinations
The permissions that enable AWS privilege escalation fall into two groups: single IAM actions that reach higher privilege on their own, and combinations that chain a weaker permission with a compute or identity action. Both are what we hunt for first on an engagement, because each one is a direct route from a limited identity to administrator. The two tables below list the ones that carry most real engagements.
Single permissions that escalate on their own
Each of these reaches higher privilege with a single API call against a principal you already control. On their own they look administrative-adjacent, but every one is an escalation primitive.
| Permission(s) | How it is abused | Result |
|---|---|---|
| iam:CreatePolicyVersion | Publish a new default version of a policy with an allow-all statement, using the set-as-default flag so no extra permission is needed | Administrator |
| iam:SetDefaultPolicyVersion | Roll a policy back to an older, more permissive version that is still present | Up to administrator |
| iam:AttachUserPolicy, iam:AttachGroupPolicy, iam:AttachRolePolicy | Attach the AdministratorAccess managed policy to a principal you control | Administrator |
| iam:PutUserPolicy, iam:PutGroupPolicy, iam:PutRolePolicy | Add an inline allow-all policy to a user, group, or role you control | Administrator |
| iam:CreateAccessKey | Mint programmatic keys for a higher-privileged user | That user's access |
| iam:CreateLoginProfile, iam:UpdateLoginProfile | Set or change the console password of a higher-privileged user | That user's access |
| iam:AddUserToGroup | Add your own user to a more privileged IAM group | That group's access |
Dangerous permission combinations
Most escalation in a real account is a combination: a permission that is harmless by itself becomes a full takeover when it is paired with a compute or identity action. The pairings below are the ones we see most often, and they are exactly what a path-mapping tool is built to surface across an account.
| Combination | How it chains | Result |
|---|---|---|
| iam:PassRole + lambda:CreateFunction + lambda:InvokeFunction | Deploy and invoke a function that carries a privileged role, running your code as that role | That role's access |
| iam:PassRole + ec2:RunInstances | Launch an instance with a privileged instance profile and read its temporary credentials from the metadata service | That role's access |
| iam:PassRole + cloudformation:CreateStack | Deploy a stack that runs as the passed role | That role's access |
| iam:PassRole + glue:CreateDevEndpoint | Create a Glue development endpoint that runs as the passed role | That role's access |
| iam:UpdateAssumeRolePolicy + sts:AssumeRole | Rewrite a role's trust policy to name your identity, then assume the role | That role's access |
| lambda:UpdateFunctionCode + an existing privileged function | Replace the code of a function that already carries a privileged role, then let it run | That role's access |
| SSRF or RCE + IMDSv1 + an over-permissive instance role | Reach 169.254.169.254 from a vulnerable application and read the instance role credentials | The instance role's access (the Capital One pattern) |
The wildcard is the common thread. An IAM policy that grants iam:* on all resources hands over the keys to the kingdom, and even a single action from the first table, or a single pairing from the second, is often enough on its own.
Our hands-on lab Escalate Privileges by IAM Policy Rollback runs one of these dangerous permissions end to end in a live AWS account.
The main AWS privilege escalation paths
Policy manipulation
If the current identity can edit policies, the fastest route is to give itself more access directly. iam:CreatePolicyVersion is the cleanest example: a new policy version can be published with an allow-all statement and marked as the default in the same call, so the attacker never needs iam:SetDefaultPolicyVersion. The inline-policy actions (iam:PutUserPolicy and its group and role variants) and the attach actions (iam:AttachUserPolicy and friends attaching AdministratorAccess) reach the same outcome by a different door.
Taking over another principal
When direct policy edits are not available, the attacker targets a principal that already has more access. iam:CreateAccessKey mints a fresh key pair for a privileged user, iam:CreateLoginProfile or iam:UpdateLoginProfile sets a console password on one, and iam:AddUserToGroup drops the attacker's own user into a privileged group. Each one borrows an identity that already holds the permissions the attacker wants.
Passing a role to a compute service
iam:PassRole is the most common and most powerful primitive, because it turns the right to hand a role to a service into code execution as that role. With ec2:RunInstances and iam:PassRole, an attacker launches an instance with a privileged instance profile and reads its temporary credentials from the metadata service. With lambda:CreateFunction, lambda:InvokeFunction, and iam:PassRole, they deploy and run a function as a privileged role. CloudFormation, Glue, and Data Pipeline all offer the same pattern. One important detail for testers: AWS GuardDuty flags instance-profile credentials used from outside the instance, so the quiet move is to drive the AWS API from inside the compromised compute instead of exfiltrating the keys.
Abusing a role trust policy
A role's trust policy decides who can assume it. With iam:UpdateAssumeRolePolicy and sts:AssumeRole, an attacker rewrites that trust policy to name their own identity and then assumes the role, inheriting whatever it can do. This is a favorite because it is a single configuration change against a role that was never meant to be assumable by the attacker.
From a server into the account
Privilege escalation often begins outside IAM. Remote code execution on an EC2 instance, or a server-side request forgery bug that can reach 169.254.169.254, exposes the instance role's temporary credentials through the Instance Metadata Service. On IMDSv1 those credentials are one unauthenticated request away, which is why SSRF is far more severe in the cloud than on-premises. From there the attacker holds the instance role and continues the chain inside the account.
Both halves of this path are hands-on in our labs: SSRF to Pwned shows how severe SSRF becomes on an EC2 instance, and Command Injection to EC2 User Data Privilege Escalation runs the server-into-account chain end to end.
A real-world incident: Capital One, 2019
The 2019 Capital One breach is the textbook example of this chain. An attacker reached a misconfigured web application firewall, used server-side request forgery to query the EC2 Instance Metadata Service, and retrieved the temporary credentials of the instance role. Those credentials carried permissions to list and read S3 buckets, and the attacker used them to exfiltrate the personal data of more than one hundred million customers. No software was exploited inside AWS. The whole event was an SSRF reaching IMDS and an over-permissive instance role, which is exactly the server-into-the-account path above, and it remains the clearest argument for IMDSv2 and least-privilege roles.
How we test for AWS privilege escalation
Testing for escalation starts with enumerating what the current identity can actually do, then mapping which dangerous permissions or reachable roles are in play. In the ACRTP bootcamp and on engagements we use aws-enumerator to resolve the effective permissions of a recovered identity, PMapper to compute the privilege-escalation paths and permission combinations that are reachable across the account, and Pacu for its enumeration and privilege-escalation modules. GoAWSConsoleSpray turns recovered access keys into an authenticated console session, and the AWS CLI itself (iam:SimulatePrincipalPolicy and iam:GetAccountAuthorizationDetails) confirms each candidate against the real account. The work that matters is reading the results: a permission is only an escalation when the resource it applies to actually allows it, so we verify every candidate against the live account instead of assuming it from the policy. Our Intro to AWS IAM Enumeration lab is a hands-on starting point for the enumeration step. Only test accounts you own or are explicitly authorized to assess.
Defending against AWS privilege escalation
The defense is least privilege applied with intent. Scope every IAM policy to specific resources instead of a wildcard, and never grant iam:* outside a break-glass role. Where self-service permissions are needed, constrain them with the aws:username policy variable so a user can only act on themselves, and with conditions such as aws:SourceIp to bound where calls can come from. Put a permission boundary on roles that create or modify other identities, so even a successful policy edit cannot exceed the boundary. Use service control policies and a data-perimeter model to stop cross-account and cross-service reach. Enforce IMDSv2 on every instance and set the hop limit to one, which closes the SSRF-to-credentials path that drove the Capital One breach. On the proactive side we run Prowler to surface the over-permissive grants before an attacker finds them, and our AWS IAM Access Analyzer lab walks this hardening hands-on. Finally, treat the detection signals as real: instance credentials used off the instance, a new policy version on a sensitive policy, a trust-policy change, and the creation of access keys or login profiles on other users are all high-signal events that AWS GuardDuty and CloudTrail can surface.
How to learn AWS privilege escalation
AWS privilege escalation is learned by running the chains against real, authorized accounts. A good starting point is our beginner's guide to hunting AWS IAM privilege escalation with Pacu, which walks the enumeration-to-exploit loop hands-on. To go end to end, from initial access through IAM abuse, role chaining, and lateral movement into full account compromise, the Amazon Cloud Attack and Defense bootcamp leads to the ACRTP certification, with every technique run in a live AWS environment and the defensive view taught alongside the offensive one. The same primitives recur on other clouds, and our GCP privilege escalation guide maps the equivalent paths in Google Cloud. Only ever test systems you own or are explicitly authorized to assess.
Frequently asked questions
What is the most common AWS privilege escalation path?
Abusing iam:PassRole with a compute service is the most common. An identity that can pass a privileged role to EC2, Lambda, CloudFormation, Glue, or Data Pipeline can run code as that role and inherit its permissions, often reaching administrator.
Which IAM permissions are the most dangerous?
The highest-risk single permissions are iam:CreatePolicyVersion, the inline and attach policy actions (iam:PutUserPolicy, iam:AttachUserPolicy and their group and role variants), iam:CreateAccessKey, iam:CreateLoginProfile and iam:UpdateLoginProfile, and iam:AddUserToGroup. Each one reaches higher privilege with a single call against a principal you control.
Which IAM permission combinations enable privilege escalation?
The highest-impact combinations pair iam:PassRole with a compute action: iam:PassRole with lambda:CreateFunction and lambda:InvokeFunction, or with ec2:RunInstances, runs code as a privileged role. iam:UpdateAssumeRolePolicy with sts:AssumeRole rewrites a role's trust policy and then assumes it. On the host side, an over-permissive instance role reached through SSRF or RCE on IMDSv1 turns a web bug into account access, which is the Capital One pattern.
Is AWS privilege escalation an exploit or a misconfiguration?
Almost always a misconfiguration. AWS escalation is a chain of over-broad IAM grants and deploy-as-a-role paths, not a memory-corruption exploit, which is why identity and configuration are the real perimeter in the cloud.
How did the Capital One breach use privilege escalation?
The attacker used server-side request forgery to reach the EC2 Instance Metadata Service, retrieved the temporary credentials of an over-permissive instance role, and used them to read and exfiltrate data from S3. IMDSv2 and least-privilege roles are the direct mitigations.
How do I practice AWS privilege escalation safely and legally?
Use environments built for it. Hands-on labs and cyber ranges give you live, intentionally vulnerable AWS accounts to attack, which is how you build the pattern recognition that transfers to real engagements. Only test accounts you own or are explicitly authorized to assess.