Beginner Friendly
![]()
Escalate Privileges by IAM Policy Rollback
This beginner-friendly lab demonstrates how the dangerous IAM permission iam:SetDefaultPolicyVersion can be abused to self-escalate privileges in AWS. Starting from leaked credentials, you enumerate an attached IAM policy, discover a more permissive older version, and roll the default back to it to unlock access to an S3 bucket holding sensitive data.
Overview
This beginner-friendly lab demonstrates how the dangerous IAM permission iam:SetDefaultPolicyVersion can be abused to self-escalate privileges in AWS. Starting from leaked credentials, you enumerate an attached IAM policy, discover a more permissive older version, and roll the default back to it to unlock access to an S3 bucket holding sensitive data.
Scenario
During a review for Huge Logistics your team finds a passwords.xlsx file containing AWS credentials. Using those keys, you enumerate the environment and work to access sensitive data hidden in the company's cloud.
Lab prerequisites
- Basic Linux command line knowledge
- AWS CLI installed and configured
- Provided AWS access keys
Learning outcomes
- Identify the current identity with aws sts get-caller-identity
- Enumerate attached IAM user policies and list policy versions
- Compare IAM policy version documents to spot excess permissions
- Abuse iam:SetDefaultPolicyVersion to roll back to a more permissive policy version
- Enumerate and download objects from an S3 bucket
- Crack a password protected zip file using zip2john and John the Ripper with the rockyou wordlist
Real-world context
AWS warns that iam:SetDefaultPolicyVersion is a potentially dangerous permission, because an identity holding it can switch the default policy to a dormant version and directly self-escalate its own access.
KEY TAKEAWAY
An IAM policy keeps up to five versions, and only one is active. A principal holding iam:SetDefaultPolicyVersion can make any dormant version active again, inheriting whatever permissions that old version granted. No policy is edited and no new permission is created, which is why this escalation path survives most permission reviews.
What this lab covers
You start with a low-privilege set of AWS credentials and work out what they can actually do. The route upward is not a vulnerability in AWS. It is a single permission that looks administrative rather than dangerous, granted to an identity that should never have had it.
Along the way you enumerate IAM policies and their version history, identify the permission that makes escalation possible, and use the widened access to reach data in S3 that the original credentials could not touch.
It is deliberately beginner-friendly and assumes no prior AWS experience. The value is in recognizing a permission-shaped weakness rather than an exploit, which is the form most real cloud escalation takes.
How IAM policy version abuse works
AWS managed and customer-managed IAM policies are versioned. Each policy retains up to five versions, exactly one of which is the default, meaning the one actually in force. The other four sit dormant but remain fully intact, including any permissions they once granted.
Versions accumulate naturally. A team writes a broad policy during a migration, tightens it later, and the broad version stays in the history because nothing removes it. The account looks correctly scoped when you read the active policy, because the active policy is correctly scoped.
The permission iam:SetDefaultPolicyVersion changes which version is in force. An attacker holding it does not need to write a policy, attach anything, or create an identity. They enumerate the version history, find the permissive version that was tidied away, and make it current again. AWS documents this permission as one to grant carefully, and it appears in most published catalogs of IAM privilege escalation paths.
How to detect this in your own environment
Alert on the API call itself. SetDefaultPolicyVersion is rare in normal operations, appears in CloudTrail as a management event, and is enabled by default, so this is one of the few high-value detections that costs nothing to build and generates almost no noise.
Pair it with context rather than treating it in isolation. The meaningful signal is the call being made by a principal that is not a recognized change-management or infrastructure-as-code identity, or being made outside a deployment window. A pipeline rolling back a policy during a deploy looks very different from a user doing it at midnight.
Watch for what follows. Escalation is only useful if it is used, so a burst of newly successful calls from a principal that was previously getting access denied responses is corroborating evidence. Access denied events are frequently filtered out of log pipelines, which removes the clearest before-and-after signal you have.
How to prevent it
Long-lived access keys are worth eliminating wherever you can. Static keys committed to a repository or left on a developer laptop are a recurring source of valid credentials, and roles issuing short-lived credentials remove the artifact that gets stolen. That said, credentials are only one route in. Exploitation of vulnerabilities in the applications running in the cloud is now a major initial access vector in its own right, and it lands an attacker on a workload whose attached role is the thing they escalate from.
Prune policy version history. Because only five versions are retained and the oldest is deleted when a sixth is created, a permissive version can persist for years. Deleting non-default versions after a policy is finalised removes the escalation target entirely, and costs nothing.
Use permission boundaries on any identity that must hold policy-management permissions. A boundary caps the effective permissions regardless of which policy version becomes active, which turns this from an escalation into a failed attempt.
Real-world context
This is one of a well-documented family of IAM privilege escalation paths first catalogd in security research on AWS permission misconfigurations, and it remains in active use because it depends on configuration rather than a software flaw. There is no patch for it.
The broader pattern is what matters for defenders. Cloud privilege escalation frequently does not involve exploiting the cloud provider at all. It involves an identity holding one permission more than it needed, and an attacker who understands the permission model better than the team that wrote the policy. Whether they arrived with a stolen key or through a vulnerable application, the escalation step looks the same.
It maps to MITRE ATT&CK techniques T1098 Account Manipulation and T1078 Valid Accounts. Both describe activity that is, at the API level, entirely legitimate, which is precisely why permission hygiene does more here than any detection rule.
Applying this at work
- List every principal in your account holding iam:SetDefaultPolicyVersion or iam:CreatePolicyVersion. For most organizations this should be a very short list, and it usually is not.
- Audit your customer-managed policies for non-default versions and compare each against the active one. Any dormant version that is broader than current is a live escalation path.
- Delete non-default policy versions once a policy is settled. This is a housekeeping task with a direct security payoff.
- Add a CloudTrail detection for SetDefaultPolicyVersion by any principal outside your infrastructure-as-code role.
- Stop filtering access denied events out of your log pipeline. They are the cheapest early indicator of an identity probing its own limits.
Frequently asked questions
What does iam:SetDefaultPolicyVersion actually allow?
It allows a principal to change which stored version of an IAM policy is active. It does not allow writing new permissions, but because policies retain up to five versions, it allows restoring any permission set that policy previously granted.
Why is this not caught by a normal permissions review?
Because reviews read the active policy, which is usually correctly scoped. The permissive version sits in the version history, invisible unless someone explicitly enumerates non-default versions.
Is this activity logged in AWS by default?
Yes. SetDefaultPolicyVersion is an IAM management event and appears in CloudTrail without any additional configuration. It is rare enough in normal operations to make a high-confidence, low-noise alert.
Do I need my own AWS account to practice this?
No. The lab runs in a live AWS environment that Pwned Labs provisions for you, so there is nothing to set up and no risk to your own infrastructure.
Which certification covers this in depth?
The Amazon Cloud Red Team Professional (ACRTP) covers AWS IAM abuse and privilege escalation in full, and is assessed hands-on in a live AWS account.
Cloud Security Training To Protect Your Business
Pwned Labs for Business gives your team access to dedicated business content, including labs and cyber ranges.
We also offer in-person or remote workshops, and our cloud penetration services are helping businesses become more secure!