Enumerate Permissions without Logging to CloudTrail

Original Research: Nick Frichette
Link to Tool: aws_stealth_perm_enum

After compromising an IAM credential while attacking AWS, your next task will be to determine what permissions that credential has scoped to them.

Aside from guessing, enumerating these permissions would typically require a tool to brute force them like enumerate-iam (which is a fantastic tool). The problem of course is that this will generate a ton of CloudTrail logs and will alert any defender. This poses a challenge to us, how can we enumerate permissions in a stealthy manner?

The good news is that there is a bug in the AWS API that affects 645 actions across 40 different AWS services. This bug is a result of a mishandling of the Content-Type header, and when that header is malformed in a specific way the results are not logged to CloudTrail. Based on the response codes/body we can determine if the role does or does not have permission to make that API call.

The following services are affected, although please note, that not all actions for these services can be enumerated.

application-autoscalingappstream
athenaautoscaling-plans
aws-marketplacecloudhsm
codecommitcodepipeline
codestarcomprehend
curdatapipeline
daxdirectconnect
discoveryforecast
gamelifthealth
identitystorekinesis
kinesisanalyticsmacie
mediastoremgh
mturk-requesteropsworks-cm
personalizeredshift-data
route53domainsroute53resolver
sagemakersecretsmanager
shieldsms
snowballsupport
taggingtextract
translateworkmail
For an in depth explanation for the bug, please see the original research. In this article we will just discuss how to take advantage of it.

There are some conditions to the enumeration, and they are defined below.

1 - The AWS service uses the JSON 1.1 protocol.
2 - The API actions returns a unique error code depending on the permission set.
3 - The resource associated with that action is set to “*”.

To perform the enumeration there is a script here. Setting the credentials as environment variables and then running the script will inform you what API permissions you have available to you.

Proof of Concept