---
title: "AWS IAM Privilege Escalation Techniques - Cybr"
description: "How attackers abuse IAM permissions like iam:CreateAccessKey and iam:AttachUserPolicy to escalate privileges in AWS, with example policies, exploits, and fixes."
url: https://cybr.com/cloud-security/aws-iam-privilege-escalation-techniques/
---

# AWS IAM Privilege Escalation Techniques

How attackers abuse IAM permissions like iam:CreateAccessKey and iam:AttachUserPolicy to escalate privileges in AWS, with example policies, exploits, and fixes.

Christophe

Published February 7, 2024 · Updated October 27, 2026

An IAM privilege escalation (PrivEsc) happens when an identity with limited permissions uses one of those permissions to give itself, or a principal it controls, more access. Most of them come down to a single overly broad IAM permission, often granted with `Resource: '*'`.

This post walks through the most common IAM privilege escalation techniques in AWS. For each one, you'll find an example vulnerable policy, an example exploit, the impact, and how to prevent it. Only test these in environments you own or are authorized to assess.

## `iam:CreateAccessKey`

### Example vulnerable policy

```
Operations:
    Type: AWS::IAM::Group
    Properties:
      GroupName: Operations
      Policies:
        - PolicyName: OperationsPolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - "iam:CreateAccessKey"
                Resource: '*'
```

Users in this `Operations` group have access to create access keys for all users in this AWS environment because of `Resource: '*'`, even for administrators.

### Example exploit

```
aws iam create-access-key \
    --user-name <victim-username> \
    --output text | tee creds.txt
```

This fails if the target user already has two access keys, which is the IAM limit. An attacker who also has `iam:DeleteAccessKey` could delete one first, but that's noisy.

This will output the access key and you can always retrieve with:

```
cat creds.txt
```

Try it yourself in our [hands-on lab](https://cybr.com/hands-on-labs/lab/iam-createaccesskey-privesc/).

### Impact

The potential impact of this attack is anything from getting access to a low-privileged IAM user all the way to gaining admin privileges, depending on which user the threat actor is able to create access keys for.

### How to prevent

Prevent the creation of any new keys in all of your AWS environments with SCPs. This can be a drastic solution for some organizations who still rely on long-term access keys, however, it is a good goal to strive towards as [outlined here](https://cybr.com/cloud-security/ditching-aws-access-keys/).

For organizations who simply can't yet get rid of long-term access keys, recommendations are to:

- Limit access key creation to higher privileged users only, or
- Ensure that users can *only create keys for their own users*

This issue is primarily a concern when 1 user has `iam:CreateAccessKey` permissions for another user as well.

## `iam:CreateLoginProfile`

### Example vulnerable policy

```
Operations:
    Type: AWS::IAM::Group
    Properties:
      GroupName: Operations
      Policies:
        - PolicyName: OperationsPolicy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - "iam:CreateLoginProfile"
                Resource: 'arn:aws:iam::123456789012:user/*'
```

Users in this `Operations` group have access to create login profiles with whatever password they want (within the AWS account's password policy allowance) for all users in this AWS environment because of `Resource: 'arn:aws:iam::123456789012:user/*'`, even for administrators.

### Example exploit

```
aws iam create-login-profile --user-name <victim-username> \
    --password '<arbitrary-password-here>' \
    --no-password-reset-required
```

Which returns:

```
{
    "LoginProfile": {
        "UserName": "<victim-username>",
        "CreateDate": "2023-11-30T21:46:56+00:00",
        "PasswordResetRequired": false
    }
}
```

Note that this action will only work if the IAM user does not already have a login profile. Otherwise, you can try to use `iam:UpdateLoginProfile`.

Try it yourself in our [hands-on lab](https://cybr.com/hands-on-labs/lab/iam-createloginprofile-privesc/).

### Impact

The potential impact of this attack is anything from getting access to a low-privileged IAM user all the way to gaining admin privileges, depending on which user the threat actor is able to create a login profile for.

### How to prevent

The best way to prevent this issue is to stop using IAM Users altogether and instead use [IAM Identity Center](https://cybr.com/cloud-security/aws-iam-identity-center/). This can take time to implement, however. As an alternative, if you have to grant this permission, make sure it only gives users the ability to create their own login profile only (unless they're an admin user who's meant to be able to do this).

## `iam:UpdateLoginProfile`

Exactly the same details as the above `iam:CreateLoginProfile` except the permission is `iam:UpdateLoginProfile` and the command is different:

```
aws iam update-login-profile --user-name <victim-username> \
    --password '<arbitrary-password-here>' \
    --no-password-reset-required
```

Try it yourself in our [hands-on lab](https://cybr.com/hands-on-labs/lab/iam-updateloginprofile-privesc/).

## `iam:SetDefaultPolicyVersion`

### Example vulnerable policy

```
DevelopersManagedPolicy:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      ManagedPolicyName: DevelopersPolicy
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Action:
              - "iam:Get*"
              - "iam:List*"
              - "iam:SetDefaultPolicyVersion"
            Resource:
              - 'arn:aws:iam::123456789012:user/name'
              - 'arn:aws:iam::123456789012:policy/name'
```

Users with this policy will have access to roll back their policy versions to a prior version. When you make changes to managed policies, by default, AWS will create a new version and keep prior versions (IAM stores [up to five versions](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-versioning.html) of a customer managed policy, including the default). With the `iam:SetDefaultPolicyVersion` access, a user is able to change the currently active policy version, which can lead to PrivEsc.

For example, let's say that you create a new user and you create a new managed policy for that user (or group of users). To start, you give that managed policy full admin access, and then you go back and modify the permissions to be much more restrictive. That policy will now have a v1 and v2: v1 grants full admin privileges but is no longer the active version, and v2 is the restrictive default. The user realizes this, and they realize they have `iam:SetDefaultPolicyVersion` access, so they could set v1 as their currently active (default) policy version, which would grant them admin privileges again.

### Example exploit

```
aws iam set-default-policy-version \
  --policy-arn arn:aws:iam::123456789012:policy/cg-raynor-policy-iam_privesc_by_rollback_cgidky1t7bwmv8 \
  --version-id v1
```

For more information, view this [free lab from CloudGoat](https://github.com/RhinoSecurityLabs/cloudgoat/tree/master/cloudgoat/scenarios/aws/iam_privesc_by_rollback), and [our hands-on lab](https://cybr.com/hands-on-labs/lab/privilege-escalation-via-iam-versions/).

### Impact

The potential impact of this attack is anything from no change in permissions, minor changes in permissions, or gaining admin privileges, depending on what policy versions the user has access to restore.

### How to prevent

The best way to prevent this issue is to stop using IAM Users altogether and instead use [IAM Identity Center](https://cybr.com/cloud-security/aws-iam-identity-center/). This can take time to implement, however. As an alternative, block access to this action for most users except for admin users, and even then, consider the implications.

## `iam:AddUserToGroup`

### Example vulnerable policy

```
SeniorDeveloper:
    Type: AWS::IAM::User
    Properties:
      UserName: SeniorDev
      Policies:
        - PolicyName: senior-manager-policy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - "iam:AddUserToGroup"
                Resource:
                  - 'arn:aws:iam::123456789012:group/division_it/engineering/*'

Developers:
    Type: AWS::IAM::Group
    Properties:
      GroupName: Developers
      Path: '/division_it/engineering/development/'
      Policies:
        - PolicyName: developers-policy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - "whatever-actions-here"
                Resource: '*'

SecretsManagementGroup:
    Type: AWS::IAM::Group
    Properties:
      GroupName: SecretsManagement
      Path: '/division_it/engineering/secrets/'
      Policies:
        - PolicyName: secrets-management-policy
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - secretsmanager:whatever-actions-here
                Resource: !Sub "arn:aws:secretsmanager:us-east-1:123456789012:secret:some-secret-value-here"
              - Effect: Allow
                Action: secretsmanager:ListSecrets
                Resource: "*"
```

In this scenario, let's say that the `SeniorDev` user is part of the `Developers` group but *not* the `SecretsManagementGroup`. However, she has an inline policy granting her access to `iam:AddUserToGroup` to the resource ARN: `arn:aws:iam::123456789012:group/division_it/engineering/*`

The `Developers` group path is `'/division_it/engineering/development/'`

The `SecretsManagementGroup` group path is `'/division_it/engineering/secrets/'`

Because the `SeniorDev` resource ARN value has a `*` after the `/division_it/engineering/`, that includes the `SecretsManagementGroup` which is an entirely different team/group that she's not supposed to be able to access. But because she can add users to that group, she can add herself or another user to the `SecretsManagementGroup` and gain access to the secret value with this ARN: `arn:aws:secretsmanager123456789012:secret:some-secret-value-here`.

### Example exploit

```
aws iam add-user-to-group \
  --group-name SecretsManagement \
  --user-name SeniorDev
```

Try it yourself in our [hands-on lab](https://cybr.com/hands-on-labs/lab/iam-addusertogroup-privesc/).

### Impact

The potential impact of this attack is anything from no change in permissions, minor changes in permissions, or gaining admin privileges, depending on what group(s) the user is able to add themselves or others to.

### How to prevent

The best way to prevent this issue is to stop using IAM Users altogether and instead use [IAM Identity Center](https://cybr.com/cloud-security/aws-iam-identity-center/). This can be a big step for some organizations, however. As an alternative, make sure that the resource ARN for which group a user can add users to is very specific! Avoid using `*` when possible.

## `iam:AttachUserPolicy`

### Example vulnerable policy

```
SeniorDeveloper:
    Type: AWS::IAM::User
    Properties:
      UserName: SeniorDev
      Policies:
        - PolicyName: senior-manager
          PolicyDocument:
            Version: '2012-10-17'
            Statement:
              - Effect: Allow
                Action:
                  - "iam:AttachUserPolicy"
                Resource:
                  - 'arn:aws:iam::123456789012:user/*'
```

In this scenario, the `SeniorDev` user has `iam:AttachUserPolicy` privileges, for the resource ARN of `'arn:aws:iam::123456789012:user/*'`.

This is a very broad resource set, since it’s essentially granting access to AttachUserPolicy on all users within this AWS account! That includes your own user. However, it could be an even more specific ARN like `arn:aws:iam::123456789012:user/seniordev`, and this would still apply.

The danger of AttachUserPolicy is that it was designed to attach managed policies, including AWS managed policies. That’s a lot of potential policies, some of which grant admin-level permissions! ([Example](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/policy-list.html)). This means our not-so-friendly `SeniorDev` can grant themselves full admin privileges.

### Example exploit

```
aws iam attach-user-policy \
  --user-name SeniorDev \
  --policy-arn arn:aws:iam::aws:policy/AdministratorAccess
```

Try it yourself in our [hands-on lab](https://cybr.com/hands-on-labs/lab/iam-attachuserpolicy-privesc/).

### Impact

The potential impact of this attack is anything from no change in permissions, minor changes in permissions, or gaining admin privileges, depending on what managed policy they attach to themselves or other users in the account.

### How to prevent

Avoid granting this policy unless it's for very specific use cases, in which case you would also want to restrict which managed policies the user is able to attach with a condition such as `"Condition": {"ArnEquals": {"iam:PolicyARN": ["arn:aws:iam::123456789012:policy/ApprovedPolicy"]}}`. [Permissions boundaries](https://cybr.com/cloud-security/aws-iam-least-privilege/) can also cap the user's effective permissions, as long as you deny them the ability to change or remove their own boundary.

## `iam:AttachGroupPolicy`

### Example vulnerable policy

```
DevelopersManagedPolicy:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      ManagedPolicyName: DevelopersPolicy
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Action:
              - "iam:AttachGroupPolicy"
            Resource:
              - 'arn:aws:iam::123456789012:group/division_it/engineering/*'
```

In this scenario, whoever is part of this `/division_it/engineering/` group has the `iam:AttachGroupPolicy` privileges for groups within that path.

This is a very broad resource set and a very dangerous permission to apply without boundaries, since it's essentially granting access to attach any policy to the group. Anyone assigned to that group would then receive those permissions.

The danger of AttachGroupPolicy is that it was designed to attach managed policies, including AWS managed policies. That’s a lot of potential policies, some of which grant admin-level permissions! ([Example](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/policy-list.html)).

### Example exploit

```
aws iam attach-group-policy \
  --group-name <group-name> \
  --policy-arn arn:aws:iam::aws:policy/AdministratorAccess
```

Try it yourself in our [hands-on lab](https://cybr.com/hands-on-labs/lab/iam-attachgrouppolicy-privesc/).

### Impact

The potential impact of this attack is anything from no change in permissions, minor changes in permissions, or gaining admin privileges, depending on what managed policy they attach to the group and who has access to that group.

### How to prevent

Avoid granting this policy unless it's for very specific use cases, in which case you would also want to restrict which managed policies the user is able to attach with a condition such as `"Condition": {"ArnEquals": {"iam:PolicyARN": ["arn:aws:iam::123456789012:policy/ApprovedPolicy"]}}`. [Permissions boundaries](https://cybr.com/cloud-security/aws-iam-least-privilege/) can also cap the user's effective permissions, as long as you deny them the ability to change or remove their own boundary.

## `iam:PutUserPolicy`

This permission lets a user create or update an inline policy on a user. If the resource isn't restricted, an attacker can write an inline policy that grants themselves (or any other user) full admin access.

```
aws iam put-user-policy \
  --user-name <your-username> \
  --policy-name privesc \
  --policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"*","Resource":"*"}]}'
```

Try it yourself in our [hands-on lab](https://cybr.com/hands-on-labs/lab/iam-putuserpolicy-privesc/).

### Impact

Full admin access, since the attacker writes the policy themselves.

### How to prevent

Only grant `iam:PutUserPolicy` to administrators, and never with `Resource: '*'`. Prefer managed policies over inline policies, and use [permissions boundaries](https://cybr.com/cloud-security/aws-iam-least-privilege/) when you need to delegate IAM administration.

## `iam:PutGroupPolicy`

The group version of `iam:PutUserPolicy`: it lets a user create or update an inline policy on a group. If the attacker belongs to a group they can write policies for, they can grant that group, and therefore themselves, admin access.

Try it yourself in our [hands-on lab](https://cybr.com/hands-on-labs/lab/iam-putgrouppolicy-privesc/).

### Impact

Full admin access for every member of the group.

### How to prevent

Same as `iam:PutUserPolicy`: restrict it to administrators, scope the `Resource` to specific groups, and use permissions boundaries when delegating.

## `iam:AttachRolePolicy`

This permission lets a principal attach a managed policy to a role. An attacker who can assume a role (or who is running as that role, for example from a compromised EC2 instance or Lambda function) and can attach policies to it can attach `AdministratorAccess`:

```
aws iam attach-role-policy \
  --role-name <role-name> \
  --policy-arn arn:aws:iam::aws:policy/AdministratorAccess
```

This is the technique used in the large-scale extortion campaign described in our [real-world case studies](https://cybr.com/cloud-security/open-source-aws-security-tools/#case-studies). Try it yourself in our [hands-on lab](https://cybr.com/hands-on-labs/lab/iam-attachrolepolicy-privesc/).

### Impact

Anything from minor changes to full admin access, depending on which managed policies the attacker can attach.

### How to prevent

Don't grant `iam:AttachRolePolicy` to roles used by workloads. Where you have to delegate it, scope the `Resource` to specific roles, use the `iam:PolicyARN` condition key to limit which policies can be attached, and require a permissions boundary on the role.

## `iam:PutRolePolicy`

The inline-policy version of `iam:AttachRolePolicy`: it lets a principal create or update an inline policy on a role, so the attacker can write whatever permissions they want into a role they can use.

Try it yourself in our [hands-on lab](https://cybr.com/hands-on-labs/lab/iam-putrolepolicy-privesc/).

### Impact

Full admin access for anyone who can use the role.

### How to prevent

Restrict it to administrators, scope the `Resource` to specific roles, and use permissions boundaries when delegating role management.

## `iam:DeactivateMFADevice`

This permission lets a principal deactivate a user's MFA device. On its own it doesn't grant new permissions, but it removes a layer of protection. Combined with a password the attacker already has (or can set with `iam:UpdateLoginProfile`), it can let them sign in as the victim, and it breaks any policy or trust policy that relies on `aws:MultiFactorAuthPresent`.

### Impact

Loss of MFA protection on the targeted users, which can turn other weaknesses into full account takeover.

### How to prevent

Only let users manage their own MFA devices, using a `${aws:username}` resource condition, and only allow `iam:DeactivateMFADevice` when the request itself was made with MFA. Alert on `DeactivateMFADevice` events in CloudTrail.

## How to detect these PrivEscs in your environments

Every technique on this page is an IAM API call, so each one shows up in AWS CloudTrail with an `eventSource` of `iam.amazonaws.com` and an `eventName` that matches the action, like `CreateAccessKey`, `AttachUserPolicy`, or `PutRolePolicy`. Alert on those events, especially when the caller is changing permissions for someone other than themselves or when they come from an unusual identity. Amazon GuardDuty also flags some of these patterns as suspicious IAM activity.

For a list of IAM events (and more) worth alerting on, see [AWS CloudTrail events to monitor and alert on](https://cybr.com/cloud-security/aws-cloudtrail-events-to-monitor/). To practice finding these attacks in logs, see [AWS Detection Engineering with Grimoire](https://cybr.com/cloud-security/aws-detection-engineering-with-grimoire/).

## Additional resources

[AWS IAM PrivEsc to S3 data - Cybr CTF Walkthrough](https://www.youtube-nocookie.com/embed/vGTPtJNFCMc)

- Learn most of these PrivEscs hands-on in our [IAM Privilege Escalation Labs](https://cybr.com/courses/iam-privilege-escalation-labs/) course, and follow the [AWS IAM Privilege Escalation Learning Path](https://cybr.com/cloud-security/aws-iam-privilege-escalation-learning-path/).
- Before you escalate, you enumerate: see [AWS IAM enumeration CLI commands](https://cybr.com/cloud-security/aws-iam-enumeration/).

## Filed under

- [Cloud Security](https://cybr.com/cloud-security/)
- [Red Team](https://cybr.com/red-team/)
- [AWS](https://cybr.com/tag/aws/)
- [AWS Security](https://cybr.com/tag/aws-security/)
- [IAM](https://cybr.com/tag/iam/)
- [Pentesting](https://cybr.com/tag/pentesting/)

## Comments

Loading comments…

Recommended resources

[![Explore the AWS Certified Security Specialty course](https://media.cybr.com/2023/12/cybr-aws-security-specialty-banner-768x432.jpg)](https://cybr.com/courses/aws-certified-security-specialty-course/)

## Build practical AWS security skills

Start with the core services, then prepare for the AWS Certified Security Specialty exam with guided lessons and hands-on practice.

[Introduction to AWS Security](https://cybr.com/courses/introduction-to-aws-security/) [Security Specialty course](https://cybr.com/courses/aws-certified-security-specialty-course/)
