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
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.
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
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
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
AWS_PROFILE
is set in your environmentAssuming your lambda function is called EnumLambda
, and the target AWS Account ID is 111111111111
, the attack steps to verify this technique are as follows
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 --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\"}"
}
remove-permission
aws lambda remove-permission --function-name EnumLambda --statement-id enum
You can grab the script to perform this attack from our Github here
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
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.