The Anatomy of an IAM Cyber Attack on AWS

Dror Zalman

Published:

Sep 23, 2021

Reading time:

8 Minutes

3:10 am

After about two hours, the scan of Acme Inc.’s web site was almost complete. Adriana hadn’t found anything and was about to give up when all of a sudden: Access Denied! With a little digging, she found a URL with “newtest” in it. It appeared to be a test for a new page. Interesting, she thought, the change language referred to a local file, could this be something? Yes! Trying 169.254.169.254 succeeded and she managed to extract AWS credentials. She looked to see if any of the credential’s permissions were useful to her. Most of them had low permission access, but then she noticed something interesting… a “role” with a policy attached named “devops_stuff_do_not_delete”. She examined this role more closely. Yes, an admin role that can be assumed by anyone. Jackpot!!

This type of identity and access management (IAM) risk is very real. While debugging an issue DevOps allows admin permissions for their testing. Then an attacker finds a forgotten unpatched vulnerability (in this example a server-side request forgery vulnerability) that allows her to compromise an instance and get credentials. The attacker then uses these credentials to use the DevOps role with the permissive policy and — the breach occurs.

Note: 169.254.169.254 is used in Amazon EC2 and other cloud computing platforms to distribute metadata to cloud instances.

Basic AWS IAM

To understand how this IAM cyber attack scenario played out, let’s start with a simple explanation of how AWS Identity and Access Management works. We can break IAM policies into three main components:

  1. Who has access to the environment? — principal – identity like a service, user, role, etc.
  2. What are they allowed to do? — actions – policies with permissions like s3:GetObject, ec2:DescribeInstances, etc.
  3. Which assets can they access? — resources like S3, EC2, Lambda, etc.

Note: AWS best practices endorse a fourth component known as conditioning, which allows creation of a pre-condition that must be met before permissions are granted. For example, only allowing requests from a certain account or user.

An SSRF Vulnerability

Now let’s suppose a cyber attacker found a website that’s running an unpatched application containing a common server-side request forgery (SSRF) vulnerability. An SSRF vulnerability can allow an attacker to induce a server-side application to make HTTP requests to an arbitrary domain of the attacker’s choosing, e.g., the web URL http://coolwebsite.com/url?eng.php. Under normal circumstances, the website will provide the english page via eng.php. However, if an attacker changes the eng.php filename to point to a different path, such as a website, the web server will dutifully carry out this request. Now if the target of the request is an internal resource (like the instance metadata server) it will respond since the origin of the request comes from an internal source. For more details on this vulnerability see the article : Steal EC2 Metadata Credentials via SSRF.

Roles Basics

To fully appreciate the example above, we need to learn a little more about AWS IAM roles. In AWS, user identities are provided with an authentication token. But what if you wanted to grant a third-party service or tool access to your environment, or maybe an application like the above web server? It would not be easy to create and maintain a user for each service/app/vendor. AWS thought about this issue and provided a solution named IAM role. A role does not have username/password or access key. A role is a standalone identity with no explicit user. Think of it as a boarding pass for an account or resource. This boarding pass is pre-granted with specific permissions (or all permissions) to be used against a specific service (or all services). Roles can be assumed by users, other roles, AWS services, or an entire account (all users from that account), and doing so grants the one who assumes it the permissions and resource it has.

The Ability to Assume Another Role

Back to Adriana, our hacker. She used the role she found in the instance via an SSRF vulnerability and figured out that this role does not provide much, but she also found one very simple and important permission that this role DOES have, which is the ability to assume another role. The identity that wishes to assume the role needs to have permissions to do so, meaning that our web server instance (in this example) was granted permissions to assume the role that was found in the instance metadata. This role also had its own permissions to assume another role. Looking around, our attacker found there was a role with pre-granted permissions (policy) that had a very interesting name (“devops_stuff_do_not_delete”). Trying to assume the role succeeded since the role from the web server (now used by our hacker) was allowed to assume this DevOps role AND the DevOps role was allowed to be assumed by anyone. In this example, the DevOps role had very extensive permissions that gave our hacker full permissions to the account.

The Anatomy of an IAM Attack Vector

We can now break down this cyber attack vector into the following parts:

  1. SSRF vulnerability on an Internet-facing web server
  2. Ability to easily access instance metadata service on the local web server (not using IMDSv2)
  3. Allowed actions (permissions) attached to the instance allowing it to assume a role (sts:PassRole)
  4. Allowed actions (permissions) attached to the “DevOps” role (trust policy) that allow anyone to assume this role with no restriction
  5. Allowed permissive actions (administrator permissions) attached to the DevOps role without strict conditions (non least-privilege approach)

IAM Misconfigurations Provide Ample Opportunities to Attackers

This specific attack vector was very fruitful for Adriana. IAM configuration can be very complex, and misconfigurations occur when best practices are not followed. IAM misconfigurations also provide a lot more possibilities for attackers to use privilege escalation attack vectors. For example, when an IAM role is assumed by an identity, this identity can be an external identity. This means a user or a role that is not part of the same account as the service can use this role for access to the account based on the role permissions. Stay tuned and follow for Part 2 of our AWS IAM tech series by Orca for more information on account trust in the wild.

Orca and Misconfiguration Detection

In Orca’s security research team, we encounter many IAM misconfigurations, most of the time they are made by the lack of a complex IAM schema or just by human error (like when a QA engineer needs a “role” to conduct a time sensitive test and puts a  * in the resource and then forgets to clean it up later). Good IAM hygiene means following the least privilege approach and cleaning up roles/users/groups and permissions no longer needed or never used. Let’s look at some examples of common misconfigurations we encounter daily at Orca.

 

Cross-Account Access without external ID – alert for any role that allows it to be used from an external account without extra security measures like conditions. We’ve seen this alert at least once within 73% of our customers, while the highest number of alerts per organization is 50%.

 

Instance Profile with Administrator Privileges – alert on any instance that has a role attached with administrator policies attached. We’ve seen this alert at least once within 33% of our customers, while the highest number of alerts per organization is 58%.

Hopefully the “Golden Role” Doesn’t Lead to Crown Jewels

Now let’s look at what happened after our attacker took control of the “golden role.” She probably searched for some crown jewels. Most organizations have sensitive information that attackers seek, like databases, private repositories, documents, emails, etc. Some are protected using the Service Control Policies IAM mechanism and some are protected by other means, like private keys, passwords, networking boundaries (like security groups and ACLs). Either way, once an attacker finds a way to move laterally in the account, it’s just a matter of time (and some luck) until your most sensitive information finds itself magically outside your organization.

How to Catch IAM Misconfigurations Before a Hacker

To avoid the above scenario, DevOps teams need to be able to catch IAM misconfigurations and lateral movement opportunities before an attacker. This is unlikely to happen if you’re using a cloud security posture management (CSPM) solution, which focuses only on control plane data. By only looking at the data that comes from the cloud provider’s API (and not workload data), one might miss authentication keys saved on local assets, misconfigurations on servers, secrets hidden in plain sight like in documents, notes, scripts, environment variables, and so on.

The answer is to use something Gartner calls a cloud native application protection platform (CNAPP), like Orca. A CNAPP looks at both the cloud infrastructure plane and workloads to give you a complete picture of both. Thus, Orca finds secrets, IAM misconfigurations, and vulnerabilities on the cloud infrastructure plane AND on workloads. And with its agentless approach, Orca has you 100% covered by scanning every workload with no gaps in coverage so you can work at DevOps speed.


Orca specializes in AWS Cloud Security, Google Cloud Platform Security, and Microsoft Azure Cloud Security.

Dror Zalman