Why IAM:PassRole Can Be Dangerous If Not Configured Correctly

If you’ve been involved or interested in AWS security you’ve no doubt heard that IAM:PassRole can be dangerous if it’s not been configured correctly. I’ve made this blog post to show a logical flow an attacker may take if they are able to compromise an AWS Role that has the IAM:PassRole permission.

The goal of our attacker will be to obtain a secret that has been created in AWS secrets manager.

The Entry Point

How did the attacker get into the account in the first place? For our example, we will assume one of our developers has been compromised and the attacker has gained their AWS credentials. Our developer has been given a role that allows the creation of EC2 instances and the ability to pass roles to those EC2 instances:

To confirm, this is a poor policy from a security perspective and has only been created this way to make the demo more simple. Always ensure you are allowing specific actions rather than using wildcards. Additionally, the resources section should always be limited.

With the current state of cloud security, it’s very unlikely an attacker will compromise your account from an external source (unless you’ve posted keys into git etc). They will most likely make the hop from a compromised on-premise infrastructure.

Escalating To An Admin User

After logging into the AWS console the attacker will begin to work out their current permissions. From the role above we know we can launch EC2 instances and pass roles to them. Therefore, our plan of attack will be as follows:

  • Launch a new EC2 instance with an SSH Key we control
  • Pass the Administrator user to the EC2 Instance during launch
  • Log in to the Instance and start making calls to the API as an Administrator.

However, before we begin this let’s take a look at the secret we are trying to obtain:

Currently, we don’t have permission to list the secrets or view them.

Let’s get our EC2 booted up:

While creating the EC2 instance we can see that we have the option to assign an “admin_user” to the instance. We will select that, we will also create our own set of SSH keys.

After the instance has launched, log in with the SSH keys we created.

Validating Our Access

After accessing the instance we want to grab the credentials that were assigned to the instance. We can do this by calling the metadata service.

curl http://169.254.169.254/latest/meta-data/iam/security-credentials/admin_user

The role we assigned to the instance is “admin_user”. Here you will find an access key and the secret access key, from here you can either extract these credentials and use them on a local machine (to access the AWS CLI) or set up the CLI on the current machine.

Stealing The Secret

Now that we have set up the CLI we can start listing and retrieving secrets with the following commands:

Listing all secrets:

aws secretsmanager list-secrets --region eu-west-2

Retrieving a secret value:

aws secretsmanager get-secret-value --secret-id prod/bank_account --region eu-west-2

We’ve now been able to decode the secret from AWS.

Summary

What happened here? An attacker was able to compromise a set of user credentials from AWS. This could have originated from a multitude of sources such as leaked credentials in git or a user being compromised.

Once the attacker had gained access to the AWS account they noticed their current role had the ability to pass EC2 instances an admin user role. After doing this the attacker was able to decrypt the secret value.

But hold up! We need a quick reality check.

gray monkey in bokeh photography

Is this a realistic attack? No, it’s not. The chances of an attacker being able to compromise a role that allows an admin user to be assigned to an EC2 instance is very slim.

However, can IAM:PassRole (setup incorrectly) lead to privilege escalation within an AWS account? Yes, it can, very much so!

The idea of this article was to demonstrate what can be done with IAM:PassRole when it’s not set up correctly. Great care should be taken when allowing certain roles to be passed to other resources.

How Can I Prevent This?

There are a few points in this attack where we could have stopped the attacker:

  • Enabling MFA. After the account was compromised the attacker would never have been able to log in if MFA was enabled. Ideally, you don’t really want to use IAM Users. It’s much better to issue temporary access keys.
  • If you are issuing temporary access keys, ensure they remain temporary and not valid indefinitely.
  • Give a specific whitelist of roles to be passed. Where IAM:PassRole does need to be assigned it’s important to give a specific allow list of roles that can be passed. This can be done by putting the specific IAM roles ARN in the “Resource” section of the policy. This would have prevented the attacker from passing the admin user.

If you’re setting up IAM:PassRole, make sure you review what extra privileges role A can gain by assigning role B to something role A controls.

You may also like...