AWS Penetration Testing – Identity and Access Management

Within AWS customers are able to manage AWS users, policies and roles through the Identity and Access Management (IAM) service. Using IAM, policies can be assigned to users and groups which grant specific permissions and access within the AWS environment.

Using IAM for enumeration

For the IAM service to be enumerated a valid set of AWS access keys would be needed. These keys allow for an initial foothold within the AWS environment and allow for programmatic access. If permissions allow it, the IAM service is a great place to start for internal enumeration as it is used to manage AWS users, groups, policies and roles.

To list users, groups and policies the current user would need some variation of iam:List* permissions. Those permissions are unlikely to have been granted on their own. However, they are included with standard AWS policies such as iam:ReadOnlyAccess and iam:FullAccess.

terminal$ aws --profile arctil iam list-users

terminal$ aws --profile arctil iam list-groups

terminal$ aws --profile arctil iam list-groups-for-user --user-name John

terminal$ aws --profile arctil iam list-attached-group-policies --group-name sysadmins

terminal$ aws --profile arctil iam list-user-policies --user-name John

In Example #1, using the first command we would be able to identify that there are two users, John and Jessica. The second command would confirm that there are also two groups, sysadmins and Managers. The third command would show that John is a member of the sysadmins group and finally the last command would show that this group has the iam:FullAccess policy assigned to it.

Although iam:List* permissions are extremely helpful it does restrict us to a broad overview of the rather than specific details. With this in mind we’re able to use iam:Get*.

Learning information about a specific user or policy is crucial as this allows us to work out exactly what is possible within the AWS environment. Additionally, this will also help us discover what other services are being used and whether we’re able to interact with them.

terminal$ aws --profile arctil iam get-account-summary

terminal$ aws --profile arctil iam get-user --user-name John

terminal$ aws --profile arctil iam get-account-password-policy

terminal$ aws --profile arctil iam get-policy --policy-arn arn:aws:iam::123456789012:policy/sysadminsPolicy

It’s worth keeping in mind, the commands above are the very top of the list when it comes to IAM List and Get usage, for a full command breakdown you can refer to the official documentation.

Understanding AWS policies

To manage user permissions AWS use policies. Policies are assigned to users and groups to determine what access that user or group has within the cloud environment.

  "Version" : "2012-10-17",
  "Statement" : [
      "Effect" : "Allow",
      "Action" : [
      "Resource" : "*"

Here we can see the iam:ReadOnlyAccess policy, this is one of the default AWS policies. All policies are written in JSON format, they have several keys but the ones we’re interested in are “Effect”, “Action” and “Resource”.

The Effect key specifies whether or not the stated actions are allowed or denied. In this example, the effect is set to Allow meaning the user can perform the actions specified within the Action key.

Lastly, the Resource key specifies the resource on which the effect takes place. As this policy offers full read-only access the resource is an asterisk or wildcard, meaning all resources.

Bruteforcing API calls using IAM

Due to the access IAM can give, this service is often heavily restricted. A user may have permission to inspect individual policies but not list all policies. This can make it somewhat difficult to find all the information required for further enumeration.

To try and get around this, penetration testers can attempt API calls to all of the IAM functionality. If an API call is unsuccessful then that user does not have access. However, if the API call is successful then it confirms that the user can use that functionality.

Due to the enormous amount of services AWS offers it would be impractical to manually make API calls for each of these. To help us speed this up we can make use of the enumerate-iam tool.

terminal$ python --access-key HSS738JS9WKS0WU --secret-key I36gd57Gf775hgct57GIun6590987FghgfcTD/97cr67

2023-11-24 12:10:57,243 - 205662 - [INFO] -- codedeploy.list_on_premises_instances() worked!
2023-11-24 12:10:57,407 - 205662 - [INFO] -- ec2.describe_import_snapshot_tasks() worked!
2023-11-24 12:13:09,877 - 205800 - [INFO] -- iam.get_user() worked!
2023-11-24 12:13:10,012 - 205800 - [INFO] -- iam.list_users() worked!
2023-11-24 12:13:10,054 - 205800 - [INFO] -- iam.list_mfa_devices() worked!
2023-11-24 12:13:06,665 - 205800 - [INFO] -- dynamodb.describe_limits() worked!
2023-11-24 12:13:06,886 - 205800 - [INFO] -- dynamodb.describe_endpoints() worked!
2023-11-24 12:13:07,003 - 205800 - [INFO] -- dynamodb.list_tables() worked!

Alternatively, another such tool which can be used to enumerate permissions within AWS is awsenum. Unlike enumerate-iam, awsenum allows penetration testers to enumerate privileges across several different services.

terminal$ python3 --profile jessie --region us-east-1 -s s3 iam
iam list-mfa-devices 
iam get-user 
iam get-account-summary 
iam list-access-keys 
iam list-account-aliases 
iam list-ssh-public-keys 
iam list-roles 
iam list-service-specific-credentials 
iam list-signing-certificates 
iam list-users 
s3 list-buckets

The example above shows that awsenum can fetch access keys from the AWS credentials file by using the –profile flag along with the name which was set during configuration. The region can be selected using the –region flag, the services can be specified with the -s flag. Once run it’ll return a list of any permissions which the specified profile has. This shows that the profile jessie has numerous IAM permissions along with S3 list capabilities.

It’s worth noting, making a large number of API calls is very noisy and can be easily noticed within CloudTrail logs.

From the output above, it’s clear that the provided access keys grant a lot of access throughout the cloud environment. Using the found privileges further enumeration can be conducted. It’s important to ensure any active services which you find are in scope for the current penetration test.

Maintaining access

It’s common practice for access keys to be rotated, this helps ensure that only authorised persons have valid keys. AWS allows administrators to easily create, invalidate and delete access keys to encourage strong security procedures.

If access has been gained through an account with high enough privilege then creating a new user could be a smart move when trying to maintain access.

terminal$ aws --profile arctil iam create-user --user-name backup_svc

terminal$ aws --profile arctil iam create-access-key --user-name backup_svc

terminal$ aws --profile arctil iam attach-user-policy --user-name backup_svc --policy-arn arn:aws:iam::aws:policy/AmazonIAMFullAccess 

If there are only a small number of users then adding a new user could draw further attention and increase the risk of detection.

Up Next “DynamoDB and RDS”

Spread the love