AWS IAM Pentesting: Privilege Escalation Paths and PMapper
Cloud Security
A hacktricks-style walkthrough of AWS IAM privilege escalation, mapping policy graphs with PMapper, and chaining iam:PassRole into admin.
By Arjun Raghavan, Security & Systems Lead, BIPI · December 7, 2024 · 12 min read
AWS IAM is the soft underbelly of most cloud breaches. Customers focus on network controls, while the actual blast radius is decided by a tangle of inline policies, managed policies, and trust relationships that no human has fully read. This post walks the offensive playbook we use during BIPI cloud pentests, from initial credential triage to full administrator pivot.
Recon: enumerate before you escalate
Assume you have an access key, either from a leaked .env, a compromised EC2 role, or a developer laptop. The first job is to figure out who you are and what you can touch, without tripping GuardDuty UnauthorizedAccess findings.
- aws sts get-caller-identity to confirm the principal and account
- aws iam get-account-authorization-details for a full policy dump if allowed
- Pacu modules iam__enum_permissions and iam__enum_users_roles_policies_groups
- ScoutSuite and Prowler for passive posture checks against the account
Mapping privilege graphs with PMapper
Principal Mapper, NCC Group's PMapper, ingests IAM into a directed graph where edges represent escalation primitives. Run pmapper graph create, then pmapper query who can do iam:CreateAccessKey with anyone. PMapper will surface principals two and three hops away from admin that an analyst would miss reading JSON by hand.
Classic escalation primitives still working in 2024
- iam:PassRole combined with lambda:CreateFunction lets you attach an admin role to a Lambda you control
- iam:CreatePolicyVersion with SetAsDefault on a customer-managed policy you are attached to
- iam:AttachUserPolicy or AttachRolePolicy when scoped without a permissions boundary
- iam:UpdateAssumeRolePolicy to add yourself as a trusted principal on a privileged role
- sts:AssumeRole into a role with a wildcard trust policy, common in cross-account setups
Lambda and EC2 as escalation vehicles
Once you find a PassRole edge, the exploit is mechanical. Create a Lambda with the target role attached, invoke it, and have it call iam:CreateAccessKey for an admin user. The CloudTrail event is lambda:CreateFunction followed by a Lambda execution, which most detection rules ignore because Lambdas are created constantly in normal operations.
Evading CloudTrail and GuardDuty
- Use the same region as legitimate workloads to blend with normal API patterns
- Avoid sts:GetCallerIdentity loops, they correlate to discovery in GuardDuty
- Prefer regional endpoints over global, which can throw CredentialAccess findings
- Throttle enumeration; Pacu has a delay flag for exactly this reason
The breach is not the access key leak. The breach is the policy graph that turns one leaked key into ten roles.
Remediation that actually moves the needle
Detection is fine, but prevention is cheaper. The controls below have stopped real attempted escalations in our customers' accounts, verified through purple team replay.
- Service Control Policies that deny iam:PassRole except to a tagged set of service roles
- Permissions boundaries on every developer and CI role, capping their effective IAM rights
- Replace long-lived access keys with IAM Identity Center and short-lived role sessions
- Run PMapper monthly in CI and fail the build on new admin-reachable principals
- Alert on iam:CreatePolicyVersion and iam:UpdateAssumeRolePolicy as high-confidence signals
Where to take this next
If you only do one thing, install PMapper against your production account and look at the principals that can reach AdministratorAccess. The graph is almost always more connected than the IAM team believes, and the conversation it starts is more useful than another posture report.
Read more field notes, explore our services, or get in touch at info@bipi.in. Privacy Policy · Terms.