Misconfigured AWS Role Leads to Cloud Initial Access and Data Compromise
There are two common ways that attackers get initial access to cloud environments: 1) finding cloud credentials lying around in data, for instance on a previously compromised end-user’s machine, or 2) exploiting a critical vulnerability in an exposed cloud-hosted application.
But there are other less common methods that work too. In this real-world external pentest, NodeZero anonymously exploited a critical AWS IAM policy misconfiguration to get initial access to a client’s AWS environment. From there it obtained read/write access to sensitive data stored in the client’s S3 buckets.
Background on AWS Cross-Account Permissions
In AWS, a role is used to define specific privileges to resources within an account. AWS IAM lets users configure the trusted entities that are permitted to “assume” the privileges of this role. These trusted entities can be users in other AWS accounts. For instance, to grant users in AWS account 999999999999 the privileges assigned to a role in AWS account 111111111111, one would configure a trust policy for that role that looks like this:
Granting cross-account access to roles is a common practice, especially for organizations managing many AWS accounts or using third-party services. Where this configuration becomes dangerous is when users open up cross-account access to all AWS accounts. The following configuration that uses a wildcard * in place of a specific account ID grants any user in any AWS account the privileges of the role.
All that’s required for someone to “assume” this role is knowledge of the role name and the AWS account ID that the role is part of. AWS clearly warns users about this dangerous configuration, but it’s still possible to set it.
There are open source attacker toolkits such as pacu that can be used to manually discover and exploit this misconfiguration. This exploit process is fully automated by NodeZero and described below.
A Real World Example
In this example, a client conducted an external pentest using NodeZero. NodeZero ran from Horizon3.ai’s cloud environment and was not provided any credentials. The client did provide NodeZero with a list of AWS account IDs that it owns.
- NodeZero used the provided AWS account IDs to anonymously enumerate AWS role names belonging to these accounts. NodeZero did this by brute force, using a large wordlist of common role names, using a technique described in this good writeup from Rhino Security Labs.
- NodeZero discovered a valid, common role name in one of the AWS accounts.
- NodeZero attempted to “assume” the role, using an AWS user configured in one of Horizon3’s own AWS accounts.
- NodeZero was able to assume the role and acquired AWS access keys with the privileges of the assumed role. NodeZero raised a weakness: H3-2021-0019: AWS Unrestricted Assume Role Access.
- NodeZero tested what the AWS access key could access. NodeZero found that it had full read/write/delete privileges to a number of S3 buckets.
- NodeZero found tens of thousands of files in these S3 buckets, some of them containing sensitive client confidential business data.
The full attack path is shown below:
It took NodeZero about 1 hour and 35 minutes to execute this attack path leading to data compromise, starting with no privileges in the form of credentials or network access. This attack was performed autonomously with no human assistance or prior scripting.
This example highlights the crucial importance of defining access control policies with the principle of least privilege in mind. This is especially important in cloud environments where credential abuse is a much bigger problem than exploitation of the cloud services themselves. Using NodeZero can provide you the attacker’s perspective to identify these kinds of issues and many more.