CRITICALPrivilege Escalation20-40 min containment15 steps across 5 phases

    IAM Privilege Escalation

    An attacker or compromised principal has escalated their IAM permissions beyond what was intended. This can happen through overly permissive IAM policies, wildcard permissions, the ability to create or modify policies, or by assuming roles with broader access. Privilege escalation is often the second step after initial access.

    Phase 1: Detection

    $ tail -f /var/log/cloudtrail/events.log
    1

    Check GuardDuty for privilege escalation findings

    GuardDuty detects anomalous IAM behavior that may indicate privilege escalation.

    GuardDuty:PrivilegeEscalation:IAMUser/AnomalousBehaviorPersistence:IAMUser/AnomalousBehaviorDiscovery:IAMUser/AnomalousBehavior
    2

    Search CloudTrail for policy modification events

    Look for IAM policy creation, attachment, or modification events by the suspected principal.

    for event in CreatePolicy PutUserPolicy PutRolePolicy AttachUserPolicy AttachRolePolicy CreateRole; do
      echo "=== $event ==="
      aws cloudtrail lookup-events \
        --lookup-attributes AttributeKey=EventName,AttributeValue=$event \
        --start-time <incident-start> \
        --max-items 10
    done
    CloudTrail:CreatePolicyCreatePolicyVersionPutUserPolicyPutRolePolicyAttachUserPolicyAttachRolePolicyCreateRoleUpdateAssumeRolePolicy
    3

    Check for new role assumptions

    An attacker with sts:AssumeRole permission can pivot to more powerful roles.

    aws cloudtrail lookup-events \
      --lookup-attributes AttributeKey=EventName,AttributeValue=AssumeRole \
      --start-time <incident-start> --max-items 20
    CloudTrail:AssumeRoleAssumeRoleWithSAMLAssumeRoleWithWebIdentity

    Phase 2: Containment

    $ ./containment.sh --isolate --immediate
    1

    Attach deny-all policy to the escalating principal

    Immediately block all actions by the principal that performed the escalation.

    aws iam put-user-policy \
      --user-name <username> \
      --policy-name DenyAll-IncidentResponse \
      --policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Deny","Action":"*","Resource":"*"}]}'
    2

    Revoke permissions on escalated roles

    If the attacker created or modified IAM policies, revert those changes immediately.

    # List policy versions (attacker may have created new versions)
    aws iam list-policy-versions --policy-arn <policy-arn>
    # Delete the attacker-created version
    aws iam delete-policy-version \
      --policy-arn <policy-arn> \
      --version-id v2
    3

    Revoke all active sessions for assumed roles

    Add time-based deny conditions to invalidate any temporary credentials obtained through the escalated roles.

    Phase 3: Eradication

    $ ./eradicate.sh --purge --verify
    1

    Revert all IAM policy changes made during the incident

    Compare current IAM policies against known-good baseline and revert any modifications.

    # Get the current policy version
    aws iam get-policy-version \
      --policy-arn <policy-arn> \
      --version-id <version>
    2

    Remove attacker-created IAM entities

    Delete any IAM users, roles, or policies created by the attacker for persistence.

    # Find policies created during incident
    aws iam list-policies --scope Local \
      --query 'Policies[?CreateDate>=`<incident-start>`].{Name:PolicyName,Arn:Arn}' \
      --output table
    3

    Review trust policies on all roles

    The attacker may have modified role trust policies to allow cross-account access from attacker-controlled accounts.

    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' 2>/dev/null
    done

    Phase 4: Recovery

    $ ./recovery.sh --restore --validate
    1

    Re-apply least-privilege policies

    Replace overly permissive policies with least-privilege versions based on actual usage.

    # Use IAM Access Analyzer to generate least-privilege policies
    aws accessanalyzer start-policy-generation \
      --policy-generation-details '{"principalArn":"<role-arn>"}'
    2

    Enable IAM Access Analyzer

    Continuously analyze IAM policies for overly permissive access.

    aws accessanalyzer create-analyzer \
      --analyzer-name "org-analyzer" \
      --type ORGANIZATION
    3

    Review and restrict iam:* permissions

    Audit which principals have iam:CreatePolicy, iam:AttachRolePolicy, and other dangerous IAM permissions.

    Phase 5: Lessons Learned

    $ cat POST_INCIDENT_REVIEW.md
    1

    Implement permission boundaries

    Use IAM permission boundaries to cap the maximum permissions that any role or user can have, even if someone attaches additional policies.

    2

    Deploy SCPs to prevent IAM escalation paths

    Use SCPs to deny iam:CreatePolicy, iam:AttachRolePolicy, and other dangerous actions except for designated admin roles.

    3

    Run regular IAM Access Analyzer checks

    Schedule periodic reviews of IAM Access Analyzer findings to detect permission drift.

    iamprivilege-escalationpolicy-modificationrole-assumptionleast-privilege

    Need Help with Incident Response?

    When an incident strikes, every minute counts. We help AWS teams prepare, detect, and respond to security incidents with proven expertise.