After you’ve mapped all the networky bits, it’s time to move on to identities and access.

AWS Identity and Access Management (IAM) is a web service that you can use to manage users and user permissions under your AWS account.

IAM is where a lot of the magic and good stuff lives. It’s extremely complicated but extremely powerful, and likely where you will be investing a lot of your reconnaissance and persistence efforts.

Listing users will give you a feel for both the size of the account and the scope of attack surface.

aws iam list-users | jq '.Users [] .Arn'

People tend to name users using either their identity or the intended purpose of the account.

"arn:aws:iam::123456789012:user/JohnSmith"

"arn:aws:iam::123456789012:user/Twitter"

"arn:aws:iam::123456789012:user/IntegrationBot"

...

In large enterprise accounts you may find yourself in the odd situation of the user list being tiny. That could be because authentication is federated via a SAML provider. To reveal this situation, list the identity providers using the IAM API.

aws iam list-saml-providers | jq ‘.SAMLProviderList [] .Arn’

Most of the major 3rd party identity services integrate seamlessly with AWS so its not unusual for one of those to be returned.

“arn:aws:iam::123456789012:saml-provider/Octa”

“arn:aws:iam::123456789012:saml-provider/PingIdentity”

The SAML provider an organisation uses for AWS authentication is highly correlated with the provider they use for other cloud services and internal systems — Yay for single sign-on. Knowing this can dramatically change other tactics you employ and reduce rage from banging your head against an invisible 2FA brick wall.

However, the true power of IAM is in roles. Roles are assumed by users authenticating via SAML. Roles are how Amazon recommends you start your EC2 instances and how it forces you to work in newer services like Lambda. Roles are the magic that gives you keyless API calls. Roles are the future.

You can use roles to delegate access to users, applications, or services that don’t normally have access to your AWS resources. For example, you might want to grant users in your AWS account access to resources they don’t usually have, or grant users in one AWS account access to resources in another account. Or you might want to allow a mobile app to use AWS resources… Sometimes you want to give AWS access to users who already have identities defined outside of AWS, such as in your corporate directory. Or, you might want to grant access to your account to third parties so that they can perform an audit on your resources.

If roles are the future, the ‘list-roles’ function is the Almanac from Back to the Future Part II.

aws iam list-roles | jq '.Roles [] .Arn'

In general role names also tend to be quite descriptive. The full list of role ARNs is critical in escalating privileges and moving laterally within AWS.

"arn:aws:iam::123456789012:role/LambdaRole"

"arn:aws:iam::123456789012:role/AdminRole"

"arn:aws:iam::123456789012:role/TestRole"

...

Conveniently, if you are bored and want to go through all user, role, and policy data with a fine-tooth comb (the hyphen is important because I’m not sure what you’d do with a fine tooth-comb?!), there’s an API to retrieve all the details at once.

aws iam get-account-authorization-details

Finally, while SSH key pairs aren’t strictly part of IAM — they are predictably part of EC2 — they are another identifier that can help with mapping how an organisation deals with access.

aws ec2 describe-key-pairs | jq '.[][] .KeyName'

You should see a list of key names, which might tell you who has access to resources and for what purpose. Shared keys might make for good targets.