Amazon Web Services (AWS) has a shared responsibility model that brings new cybersecurity challenges to organizations and professionals learning how to manage cloud security. As your business grows and data increases, the complexity of managing so much information across teams may become difficult to secure and have complete visibility in to.
An organization can have many AWS workloads and thousands of Identity and Access Management (IAM) roles. A simple misconfiguration in an AWS role created by the IAM user could lead an attacker to access resources on AWS services as an anonymous user. A misconfigured IAM role could lead to a data breach of sensitive information. In this blog, we will explore an example of how you can detect an attack on the AWS IAM roles with a misconfigured trust policy for cross-account takeovers. Let’s begin!
What are Cross-Account Users?
A cross-account user is when someone in one AWS account needs to access a resource in another AWS account. For example, let’s consider there are two accounts: Development and Production. A worker named Bob is in the Development account and needs to access an Amazon Simple Storage Service (Amazon S3) bucket in the Production account.
How to Allow Access to Resources from one Account to Another
You can grant access from one entity to access resources in another entity using roles. Roles allow you to accomplish cross-account access without any credential sharing.
What is an IAM Role?
IAM role is an IAM identity that you can create in your AWS account with specific permissions for accessing AWS resources. IAM roles are similar to IAM users. IAM roles do not have long-term credentials or access keys. IAM users or services such as Amazon Elastic Compute Cloud (Amazon EC2) can assume the role from the same AWS account or cross-account. IAM roles have permission policies. The permission policy determines what the identity can do in AWS. IAM role provides you with temporary security credentials valid for a short time.
Let’s say for example that an IAM admin of the AWS Production account needs to assist Bob from the AWS Development account to access resources or services in the Production account. To get started, the admin creates an IAM role in the Production account with a trust policy to trust the user or service from the Development account. IAM role in the Production account will allow Bob to assume the role to access production resources. IAM roles provides short-term credentials.
The below diagram describes the Production-Role in the Production account “555555555555,” trusting all the users coming from the development account “222222222222” to access the AWS S3 Bucket named “Production-S3.” Bob, coming from the Development account, should have privileges from the AssumeRole policy to access the Production-Role in the Production account. When Bob assumes the Production-Role, the Production account will issue a short-term key to access the S3 resource.
Below is a real-world example showing the Production account “949141305467” is trusting the Developer account “615233713581” to assume Production-Role. To achieve this, the IAM admin must build a trust relationship between the two accounts.
The AWS admin creates a Role in Production account called Production-Role, which trusts the developer account to assume a role in the Production account to get temporary credentials.
The trust policy document shows that all the accounts under “61523371385” can assume the Production-Role in Production account “949141305467.” AWS Policies are in JSON format.
AWS is all about misconfiguration. Think of a situation where the AWS administrator did not know the consequence of accepting all the accounts by giving an asterisk (*). The trust relationship is changed to assume the production role by anyone who owns an AWS account in the world.
When changing the trust, AWS generates a security warning when a statement in your policy allows access, which AWS considers overly permissive.
How to Detect this Misconfiguration Using LogRhythm
LogRhythm collects the logs from CloudTrail service that records AWS API calls for your AWS account.
Create an AI Engine (AIE) rule block that looks for the configuration change to the IAM Update Assume Role policy with an asterisk. Overly Permissive Policy is a configuration change to a Role where any external principal could assume the role. Monitoring configuration change for trusting all the external entities will avoid getting compromised. “UPDATEASSUMEROLEPOLICY” is an AWS API call to update the role trust policy.
When there is a configuration change to the trusted policy document with overly permission, LogRhythm’s 100-point risk-based priority scale provides a relative measure of events’ risk to help the organization prioritize analysis and response efforts.
The Drill Down of the Alarm will show the Role which got the update with a dangerous trust policy and the user who changed the configuration and other information such as the location and IP address.
Unauthenticated Role Enumeration
In reference to Figure 12 above, a change of role to asterisk will allow anyone with an AWS account in the world to assume the production role.
For this attack to be successful, there are two things an attacker needs to know. One is the victim’s AWS account ID, and the other is the victim’s role name. Let us assume the attacker managed to find the account number and role name, and he successfully assumes the role. If the role is bounded with an administrator privilege, then the entire AWS account is compromised. AWS entity trust policy is always recommended to configure for the accounts the organization trusts. The attacker will try to elevate their privilege as an admin once he assumes the role.
Let’s walk through an attack on how an attacker can brute force the role name with a wordlist by using Pacu:
The attacker logs into his own AWS account with the access key and secret access key using Pacu. The username logged in is “attacker.”
Below, you can see the attacker is logged in using his own account “attacker” in Pacu.
The attacker crafts a wordlist with some well-known random names such as Production, Admin, Dev, and Developer-role, then targets the victim account “949141305467” as an unauthenticated user brute-forcing the victim account Roles. The enumeration is successful, and the attacker finds a role called Production-Role. The session keys shown in the below image are short-term access keys.
How AWS Logging Works
When someone tries to brute force the roles, the logs are not stored in the victim account. The victim account will only log the successfully assumed role. This is a blind spot for defenders.
The below screenshot shows the successful assumption of a role from account “615233713581.” Access keys beginning with ASIA are short-term keys. You can create a rule when someone tries to assume a role, but this will generate many false positives. You can exclude based on user agents such as Terraform, AWS internal service, Lambda, and the other legitimate user agents. If you look at the below screen capture, Pacu is using Terraform as its user agent. True positives will be missed if we do the threat detection based on user agents.
The attacker managed to find the victim Production-Role using Pacu, and then he assumes the role using AWS Command Line Interface (CLI).
The attacker uses environmental variables to temporarily set the assumed session token, overriding the profile configuration file with the attacker’s credentials to the Production-Role session token.
The attacker does a traditional “whoami” to check the user he is logged in as. The attacker logged in as Production-Role with all permissions of Production-Role.
The attacker is trying to list the available EC2 instances on the victim account and the operation is denied as the victim “Production-Role” does not have the required permission.
The attacker lists the attached polices for this role and this role got overly permission for IAMFullAccess. The below attached policy is AWS managed policy to the Production-Role.
IAMFullAccess allows an attacker to control any IAM users, groups, and roles in the compromised AWS account. The attacker does not have permission over any other services such as EC2 and S3. The attacker’s end goal is to be an administrator and have full access to all the victim’s AWS services, so he must elevate his privilege as an administrator.
Once the attacker has full IAM permissions on the victim account, he then creates a username called devops-rob in the production account.
Next, the attacker could create a login profile to make the devops-rob user log in through the AWS management console or AWS-CLI, or the attacker could use a dormant account that did not have a login profile earlier. In this example, let’s say the attacker created an account called devops-rob.
Attaching the AWS managed policy “AdministratorAccess” to the devops-rob account will give the attacker full access to the victim’s AWS account.
Devops-rob is officially an administrator and has complete access to the victim’s AWS account.
How to Detect the ASSUMEROLE Attack using LogRhythm
Create an observed log rule block that looks for an “ASSUMEROLE” operation and then look for dangerous policy combination as the second rule block.
What is Dangerous Policy Combination?
When an attacker assumes a role and a dangerous IAM policy combination is applied from the assume role operations, this could lead to privilege escalation. Some of these dangerous operations are listed below:
- The assumed role creates a new policy
- Creating a new user access key
- Creating a new login profile
- Updating an existing login profile
- Attaching a policy to a user, group, or role
- Adding a user to a group
- Updating the assume policy document of a role
- Pass role operation
In our scenario, the attacker created an account called devops-rob, created a login profile, and then attached a policy “Administrator Access” to devops-rob.
You can learn more about dangerous policies for privilege escalation here.
In this scenario, LogRhythm AI Engine detects this attack with a high-risk score of 80 because the attacker assumed a role and then followed with a combination of dangerous policies. You can see from the below screen capture, attacker created a login profile at 2:19 PM with the user devops-rob and then attached an administrator policy to the “devops-rob” user at 2:24 PM. Two alarms had triggered at two different intervals. The next step is to drill down on each of the alarms.
Let’s walk through the Alarm Drill Down for the first alarm which triggered at 2:19 PM. You can see that assume role is the first operation and create login profile is the second operation by the attacker.
Alarm Drill Down shows the attacker had successfully assumed the production-role.
Now let’s look at the Alarm Drill Down for the second alarm which triggered at 2:24 PM. Assume role is the first operation and “attachuserpolicy” is the second operation by the attacker.
The drill down of the alarm will further show the role which got the update with a dangerous trust policy and the user who changed the configuration, as well as other information such as the location, IP address, user agents, and session information.
LogRhythm’s security analytics will help your incident response efforts by collecting logs from data sources such as CloudTrail, CloudWatch, and VPC flow logs. LogRhythm’s security analytics will empower you with actionable insights that are not false positives. An attacker assuming a role with short-term session keys, creating a login profile, and attaching an administrator policy is not a false positive. LogRhythm’s SmartResponse™ automation can take actions in AWS IAM to stop initial compromise or lateral movement quickly.
Final Thoughts on Detecting AWS Cross-Account Attacks
IAM roles provide secure access between cross accounts, but be sure to follow these best practices to reduce risk:
- Remove all unused IAM roles
- Roles should not be used by untrusted accounts via cross-account access
- Limit permissions as much as possible
- IAM role policies should not have “*.*”
- Protect roles with multi-factor authentication