Kloudle
academy

Cross Account IAM enumeration via Lambda Resource Policies in AWS Cloud

Riyaz Walikar
#iam-enumeration#cloudsecurity
Feature image

Background

AWS Identity and Access Management (IAM ) in many ways is the gatekeeper for resources on AWS. IAM mismanagement, leakage of credentials etc. can result in attackers gaining access to AWS services and subsequently the data and functionality they expose.

AWS IAM consists of many different types of access control entities. Users, roles, policies, groups, identity providers etc. Each of these entities can be applied to various resources within AWS to create access gates for the service that is being executed. Here are couple of examples

  1. An IAM user can login to the AWS console using a username and password or access the AWS APIs programmatically using an access key and secret
  2. A process running on an EC2 instance, wanting to write files to an S3 bucket, can generate temporary tokens by accessing the instance metadata endpoint, of an IAM Role attached to the EC2 instance

In each case, for a user or a role, a permissions policy statement is attached that defines the kind of access the user or role will have. Hence, when attempting to attack an AWS account, it’s always useful to know what kind of users, groups and roles exist on the target. An attacker can use the user or role identified to perform additional attacks, using misconfigured roles and users with weak passwords and no 2FA.

This post details a technique that uses the “Add Permission” feature in AWS Lambda to identify AWS IAM users and roles across a different AWS account without requiring any access to it. This feature essentially adds or updates a resource policy document to the lambda and can be used to leak information about IAM users and roles from a different AWS account based on error messages. Largely inspired by Daniel Grzelak’s research but using Lambda as a resource.

Fetching AWS Account IDs

To abuse the “Add Permission” feature in AWS Lambda to enumerate IAM users and roles across a different AWS account, we need to have the target AWS Account ID. Although not sensitive in isolation, the AWS Account ID can be used to chain other attacks in AWS.

In our experience, AWS account IDs are leaked through various means, some of which include

  1. Client side JavaScript in web apps using some AWS resource in the backend
  2. Mobile app code post reverse engineering
  3. GitHub and other source code repositories
  4. Public help forums - stackoverflow, dev.to etc.
  5. Public EBS and RDS snapshots
  6. Public AMIs
  7. Blog posts (and other content on the web) texts and screenshots
  8. Social Engineering

Abusing AWS Lambda to enumerate IAM

Like most IAM enumeration techniques previously discovered and documented, this technique also involves working with AWS error messages, essentially using a side channel to verify a true or false condition.

Once you have the account ID we are ready for the attack. As this is a side channel enumeration technique, you will require a list of potential user names and role names that can be tried against an AWS account. This attack will be launched using a lambda created within your own account.

The enumeration attack can be visualized as follows

  1. Invalid user/role

aws enumeration attack type

  1. Valid user/role

aws enumeration attack

Let’s see how we can do the attack first with the help of AWS commands, followed by a script that can automate the enumeration

Pre-requisites

  1. Target AWS Account ID
  2. A new lambda function in your own AWS account. The code and language are irrelevant
  3. A list of potential user names and roles you want to try against the target AWS account. You can use the default word list from Pacu for users and roles
  4. AWS cli configured for your own account. If using profiles, make sure AWS_PROFILE is set in your environment

The enumeration attack

Assuming your lambda function is called EnumLambda, and the target AWS Account ID is 111111111111, the attack steps to verify this technique are as follows

  1. Attempt to add a non-existent principal from the target AWS account to the Lambda and note the error in the response
aws lambda add-permission --function-name EnumLambda --action lambda:ListTags --statement-id enum" --principal "arn:aws:iam::111111111111:user/user-does-not-exist

An error occurred (InvalidParameterValueException) when calling the AddPermission operation: The provided principal was invalid. Please check the principal and try again.

aws lambda add-permission

  1. Attempt to add a valid principal in the target account
aws lambda add-permission --function-name EnumLambda --action lambda:ListTags --statement-id enum --principal "arn:aws:iam::111111111111:user/iamadmin"
{
   "Statement": "{\"Sid\":\"teststatement\",\"Effect\":\"Allow\",\"Principal\":{\"AWS\":\"arn:aws:iam::111111111111:user/iamadmin\"},\"Action\":\"lambda:ListTags\",\"Resource\":\"arn:aws:lambda:us-east-1:12345678901:function:EnumLambda\"}"
}

lambda add-permission

  1. Clean up after each successful user or role discovery using remove-permission
aws lambda remove-permission --function-name EnumLambda  --statement-id enum

aws lambda remove-permission

Automating the attack

You can grab the script to perform this attack from our Github here

Cross Account IAM enumeration

How can you prevent this from being abused?

At a service level there is not much that you as a user can do in terms of configuration as AWS really doesn’t have a setting to decrease error verbosity. However, somethings that you can do to improve your overall security would be to

  1. Do not use common guessable names like your real names, ‘admin’ or ‘iamuser’ or ‘s3reader’ etc.
  2. Enable 2FA on all users within IAM
  3. Do not grant unnecessary privileges to users and roles. Use the concept of least privileges everywhere.
  4. Monitor your account (and other accounts) for unusual activity like attempts at calling functions like AssumeRole, GetSessionToken etc.
  5. Minimize where your AWS account ID is displayed and made available

Conclusion

Any AWS service that uses Resource Policies, to set up permissions for users, roles and resources within AWS, is potentially vulnerable to this enumeration attack owing to the error messages that AWS provides based on the success or failure of certain commands.

A proof of concept script is also available as a part of this post, which can be used to enumerate users and roles across a different AWS account via the “Add Permission” Resource Policy feature of AWS Lambda.

As there is no easy way to prevent IAM enumeration completely, the preventive actions need to be aligned with a more defense in depth approach.

← Back to Academy