CloudMapper "find_admins" - Command to identify admin users and roles in an account

2018.06.12

RSS feed

This CloudMapper post introduces the find_admins command which identifies the admins in an AWS account as a first step toward helping to implement a least privilege strategy. Knowing which users and roles in an account can perform any action requires looking at the users and roles and seeing which custom or managed policies they have and understanding those, then looking at any groups they may be in and what policies those have. This can quickly become overwhelming so this tool helps to simplify this by only identifying the users and roles with full privileges in the account, or that can assume full privileges by abusing their current privileges.

This looks at the IAM policies in an account that directly grant *:*, or can indirectly grant that privilege due to their inclusion of actions such as iam:PutRolePolicy which can be used to add an admin policy to a role which could allow for privilege escalation. That specific action was recently found in the AWS Managed Policy AmazonElasticTranscoderFullAccess and allowed that role to escalate it's privileges. See the post AWS Security Flaw which can grant admin access! for more info on that issue. This find_admins command was partially developed as a reaction to that issue and as such can identify that problem and similar concerns.

Understanding the output

This is example output from a small account:

$ python cloudmapper.py find_admins --account prod
{"Issue": "User is admin", "Location": {"account": "prod", "user": "admin"}, "Reasons": ["In admin group: Admin"], "Severity": "INFO"}
prod    user    admin

This command prints to both stderr and stdout. The column formatted output (prod user admin) is sent to stdout, whereas the the json is sent to stderr. This allows you to send this information to multiple files if you like. You can also set a --log_level WARN to ignore the INFO level severity issues.

The stdout information will be a list of all of the users and roles in the accounts that this has identified are admins. The stderr information identifies all sorts of potential IAM issues.

The json contains the Severity (INFO, WARN, and ERROR), a generic Issue title, a Location for the item is in the IAM that generated this message, and more specific "Reasons" for why this was called out. For example, in the sample output, it is stating that a user named admin in the prod account is admin, as shown in the title User is admin. This is the same information that was sent to stdout, but importantly this also explains why this tool believes this to be true, which is that the user is in a group called Admin. These Reasons and Location info become more important to see in larger and more complex IAM setups.

Auditing

When you run this command, in addition to trying to find admin users and roles, it will display warnings about things you might want to investigate further. Some examples are:

  • Using an action of * but only on a specific resource such as an S3 bucket. This does restrict the actions that can be taken, but is usually an indication that more actions than needed were granted.
  • Any policies that allow admin that aren't the AWS managed policies AdministratorAccess or IAMFullAccess. This will identify the use of the AmazonElasticTranscoderFullAccess mentioned earlier, along with any custom policies that have been created in the account.
  • Any IAM Groups that allow admin privileges but do not have the string Admin in them. For example, someone might create a group named Test and add admin privileges to it and then forget about it.
  • Any custom policies applied to a user or role that have admin privileges.

How this works

The logic behind this command is a kludge, but in practice I've found it to work quite well. It looks at the iam get-account-authorization-details output, and looks at all managed policies in the account. It looks for any actions granting *, *:*, or iam:*. It then looks for potential privilege escalations due to a number of specific IAM actions that may have been granted. It then looks at all Groups and marks these as admin if they use one of these policies. It then looks at all Users and Roles and sees if they use one of the admin policies, if they belong to one of the admin Groups, or if they have a custom policy attached to them that acts as an admin policy.

Conclusion

This will raise some false positives and may miss some things, but has been found to be effective. Try it out by cloning CloudMapper from https://github.com/duo-labs/cloudmapper

For further improvements on implementing Least Privilege, see Duo's other open-source AWS security tool CloudTracker tool that I built with them.