IAM Bad: Privilege Escalation using Misconfigured Policies in AWS IAM (Webinar)

Riyaz Walikar
Feature image


On the occasion of Star Wars Day, Kloudle hosted a webinar on AWS IAM policies, to talk about common policy mis-configurations and to demonstrate one of them in action.

The premise was based on the Star Wars universe. As Luke Skywalker, our objective was to gain access to the Death Star’s employee database which is running as an RDS service within Darth Vader’s AWS account. As the webinar was going to demonstrate a post exploitation scenario, we started off with General Tarkin’s AWS account which we then used to escalate to administrator.

Here are all the slides from the talk including the commands and their output for the demo.

What is the webinar about?

Based on some of the registrations to the webinar, we included a quick and basic primer on what AWS IAM policies were to begin with and then moved on to the demo of a policy mis-configuration.

webinar intro

What is an AWS IAM Policy

By the AWS definition, a policy is an object in AWS that when associated with an identity or resource, defines their permissions.

AWS evaluates these policies when an IAM principal (user or role) makes a request to a service within AWS and based on the permissions in the policies determines whether the request is allowed or denied.

What is an AWS IAM Policy

By design, an AWS IAM policy is a JSON document that at its least, contains a “Statement” that describes what is the “Effect” of the policy, what “Actions” a role or user is allowed to take to which this policy is attached and what “Resource” does the policy allow you to perform the said action.

To get a complete picture of AWS IAM policies, refer to https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html

Example AWS IAM Policy

Policy definitions often use a wildcard character (*) to include a range of items that start with the same string. When used as a single character, a wildcard expands to ALL the items in that context.

For example, the policy as shown in the slide above means that the user or role to which this policy is attached would be able to perform all AWS S3 service related Get and List operations on ALL AWS services. This policy when read as is makes no sense as the Resource field has a value of ALL AWS services while the Action is limited to AWS S3 service related Get and List operations. However, this is a perfectly valid policy since when AWS interprets it, it will look for all S3 related Get and List operations on ALL services, finding them only on S3 and hence implementing this policy as a S3 Read Only policy. It is recommended to specify exact resources though to ensure readability for large policies.

Common examples of mis-configured AWS IAM Policy

AWS IAM policy mis-configurations can occur in various ways. This could be due to a broad Action or broad Resource or a combination of both, resulting in overly permissive policies. Alternatively, since AWS allows you to have upto 5 versions of a policy, only one of which is active at any given moment, there could be a policy that has a vulnerable older version that can be activated instead.

examples of mis-configured AWS IAM Policy

The first example that we saw with common mis-configurations was a policy that was not bound to a particular Action or Resource.

common mis-configurations with policies

In the slide, we have a policy that when evaluated by AWS, effectively gives the user or the role Administrative Access to the AWS account. This is one of the most dangerous policy definitions and must never be used unless absolutely required within AWS.

common mis-configuration with policies

The next example we have is that of the presence of sts:AssumeRole. This operation allows the user or the role to assume the privileges of a role in AWS.

For example, if we had access to a user with the sts:AssumeRole operation allowed, and a role with an ARN of arn:aws:iam::123456789123:role/adminrole exists on AWS for the account then the following command would generate an AWS_ACCESS_KEY_ID, a AWS_SECRET_ACCESS_KEY, and a AWS_SESSION_TOKEN which could then be used to impersonate the role with all of its privileges

aws sts assume-role --role-arn arn:aws:iam::123456789123:role/adminrole --role-session-name impersonatingrole

common mis-configuration with policies

In the next slide we have a AWS managed policy that has several different versions. This policy is not vulnerable but was used in the example to show that multiple versions of a policy can exist and we can change the default policy to an older or a newer version using the AWS console or programmatically.

Demo - Privilege Escalation by exploitation of IAM Policy

Let’s jump to our demo. We will be looking exploiting a policy that is attached to a user that has multiple policy versions. We will enumerate the versions and find a version that will provide us higher access.

Demo - Privilege Escalation by exploitation of IAM Policy

There are a few assumptions to be made and define a goal for our demo.

Demo assumption and goals

As part of the Rebel Alliance, Luke Skywalker is tasked with hacking into Darth Vader’s AWS account. Luke has obtained the AWS user credentials of General Tarkin who although is a General in the Empire, does not seem to have a lot of privileges within Vader’s AWS account.

Our objective via this demo is to identify and exploit a mis-configuration with the user’s policy definition and gain access to the employee database for the Death Star which we know is running in AWS RDS in Vader’s account.

We have already configured General Tarkin’s AWS credentials on our system as a new AWS cli profile called tarkin

identify access

We begin with identifying who we are in AWS using the stolen credentials. The command to do this is (the whoami of AWS)

aws sts get-caller-identity --profile tarkin

Once we have confirmed we have access to AWS, we attempt to access the AWS RDS service using

aws rds describe-db-instances --profile tarkin

Yeah, that did not work, so we now proceed to enumerate the attached user policies to this user to get a sense of what exactly can the user see or do in AWS.

policy list attached to a user

The command to list attached user policies is

aws iam list-attached-user-policies --user-name tarkin --profile tarkin

The username is obtained from the STS command earlier. The output of this command shows that there is a policy called EC2DataS3ReadWritePolicy

Looking at the policy’s current version gives us a sense of how many more may be there that need to be enumerated if you hope to find a weakness

policy current version

We use the GetPolicy API in AWS IAM to enumerate the version number and some other details about the policy that we saw is attached to General Tarkin’s AWS user. The command to do this is

aws iam get-policy --policy-arn "arn:aws:iam::<aws-account-number>:policy/EC2DataS3ReadWritePolicy" --profile tarkin

Next we attempt to get the actual definition of the policy json to get an idea of what is allowed and what is not.

get v6 policy json defination

To get the json definition of a policy we run the following command

aws iam get-policy-version --policy-arn "arn:aws:iam::<aws-account-number>:policy/EC2DataS3ReadWritePolicy" --version-id v6 --profile tarkin

Next we attempt to list all versions that are available for this particular policy.

list of available version of policy

We do this using the following AWS cli command

aws iam list-policy-versions --policy-arn "arn:aws:iam::<aws-account-number>:policy/EC2DataS3ReadWritePolicy" --profile tarkin

Once we have a list of all policy versions in AWS we can then enumerate each version and examine the policy json definition as shown below

get v1 defination of policy

We start with the enumeration of v1 of the policy. This can be done using the following command

aws iam get-policy-version --policy-arn "arn:aws:iam::<aws-account-number>:policy/EC2DataS3ReadWritePolicy" --version-id v1 --profile tarkin

We repeat the same command for all the versions of the policy and closely examine each of the policy definition to identify if a mis-configuration exists in any.

get v2 defination of policy

To enumerate v2 of the policy we simply change the value of —version-id to v2 as shown below

aws iam get-policy-version --policy-arn "arn:aws:iam::<aws-account-number>:policy/EC2DataS3ReadWritePolicy" --version-id v2 --profile tarkin

Finally, we arrive at v5 of the policy and see that a wildcard usage for Action and Resource gives this policy effective Administrator Access.

get v5 defination of policy

To enumerate v5 of the policy we simply change the value of —version-id to v5 as shown below

aws iam get-policy-version --policy-arn "arn:aws:iam::<aws-account-number>:policy/EC2DataS3ReadWritePolicy" --version-id v5 --profile tarkin

Once we know the version that has overly permissive json definition, we use our current privilege that gives us the IAM ability to set a default policy, to change the default policy and effectively become an AWS Administrator.

set v5 of policy as default policy

To set a different policy version as the default for a particular policy, we use the following command

aws iam set-default-policy-version --policy-arn "arn:aws:iam::<aws-account-number>:policy/EC2DataS3ReadWritePolicy" --version-id v5 --profile tarkin

Once the policy has been updated and the new permissive policy version is applied, our General Tarkin’s user account is now an AWS Administrator

access database

We can finally access the AWS RDS service to enumerate and see that there exists a death-star-employee-db that potentially contains the list of all the folks who are working on the Death Star. Luke would now proceed to access the DB using additional post exploitation techniques (that we will cover in the coming weeks)!

Post Privilege Escalation

As an attacker what are some post privilege actions you can take with the access that has now been obtained?

Post Privilege Escalation

Given that you are Luke Skywalker,

The possibilities are endless. As an attacker and the context of the attack, you could play around with different tools, the cli or simply login to the console and use the UI to navigate around.

Audience Q&A

The following questions were asked by the audience during the talk. Some of the questions have been expanded to add more context.

Q1: Is it necessary that both Action and Resource have value as * ?

Yes. This is what gives the policy Administrator rights. Essentially, the policy becomes “give this policy the ability to execute ALL operations, across ALL resources in AWS”. The AdministratorAccess AWS managed policy itself has this definition.

Q2: Assuming I have a good knowledge of building and deploying AWS services, from where do I learn AWS pentesting?

There are a lot of AWS pentesting resources on the Internet. Although, there are a lot of resources, actually doing the hands on practice is the key to learning. Practice setting up vulnerable AWS labs/environments. Practice with cURL and browse the instance metadata endpoint on an EC2, deploy a vulnerable SSRF application and use the exploit to access security credentials via instance metadata, setup and isolate security groups to your home IP address, attempt to setup a public S3 bucket etc. The attacker mindset will be honed when you know how the attack environment was setup.

At Appsecco, we had released our entire AWS and Azure Security Training last year. You can try that out too - https://github.com/appsecco/breaking-and-pwning-apps-and-servers-aws-azure-training

Q3: Will this help me with bug bounties?

Yes. If your target environment is on AWS, you can definitely pick up things like finding S3 buckets using DNS records, brute force, using Shodan to find instances and RDS endpoints that may not be linked from other apps etc.

Q4: The entire vulnerability here is old policies haven’t been removed right?

Yes, that was the primary reason. Also, the policy by its definition (at least from the name) it appears that the policy was created to move files between EC2 and S3. However, given that the policy also had some IAM level access we were able to enumerate the versions and change the default policy to a different version with excessive permissions.

Q5: Riyaz, any more complete training plan you have?

Not trainings per se, but I will be doing a lot more of these short webinars over the coming weeks and months. Mostly attack focused but hopefully some defense as well.

Q6: Do we need to give granular level access on IAM? I am just trying for my learning AWS services.

Yes. The more granular you are with your policy definition the less you are likely to fall prey to mis-configuration issues that could lead to privilege escalation or other vulnerabilities. This is true for any authorization based system on the Internet. Exactly defining what you need a particular role to do is the key to avoiding authorization related bugs.

Q7: Is the AWS security specialization certification worth it? Under what circumstances should I be aiming to get that?

The AWS security specialist is a good certification to get, especially with the content and exercises in there, you would get familiar with the different nuances of AWS services. Ensure that you couple this with lots of hands-on.

Q8: Tools for penetration testing AWS infra?

There are a lot of tools on the Internet for Penetration Testing AWS. But ensure that you are aware of the context in which you are using them. For example, if you are attempting to enumerate S3 buckets for a target organisation, you would want to possibly identify if the company uses a naming convention to name their S3 buckets and then use that to create a custom wordlist to be used for enumeration.

Q9. Have you even seen similar kind of issues in Azure or Google cloud?

Both Azure and GCP have different ways in which IAM is implemented. The same attacks may not work and you will have to attempt to discover mis-configurations in how groups are created or roles are assigned to the users.

Q10: Does AWS have a monitoring service to identify if a user’s policy has changed?

Yes. CloudTrail will pick up all the API calls that were made during this attack. Here’s how my CloudTrail looked at the end of the webinar

CloudTrail Event history


The webinar highlights how mis-configuration within IAM and user/roles and policies can lead to interesting attack vectors, some of which can lead to privilege escalation attacks as demonstrated.

Following best practices, ensuring your logging and monitoring is in place, being aware of all the objects and resources within your AWS account and working with least privileges are some of the proactive things you can do to ensure your AWS account remains safe.

Happy May the 4th to you!


This article is brought to you by Kloudle Academy, a free e-resource compilation, created and curated by Kloudle. Kloudle is a cloud security management platform that uses the power of automation and simplifies human requirements in cloud security. If you wish to give your feedback on this article, you can write to us here.

← Back to Academy