Socials

Twitter: https://twitter.com/Mako_Sec GitHub: https://github.com/MakoSec

Materials Used

  1. Pacu

https://github.com/RhinoSecurityLabs/pacu

  1. List of AWS privilege escalation methods

https://github.com/RhinoSecurityLabs/AWS-IAM-Privilege-Escalation

Introduction

Recently, I wrote a blog post on a simple method of privilege escalation in AWS. While writing that blog post I became curious of AWS managed policies and wanted to know which of them can be leveraged for privilege escalation. The reason I wanted to look into AWS managed policies in particular, is because customers have no control over managed policies. If they are being used, permissions cannot be added or removed from the policy by the customer. This can be dangerous, because if an account with a managed policy is compromised, privilege escalation can potentially occur by no fault of the customer. The results of this analysis into managed policies was not very shocking. I figured that most of the managed policies would be pretty safe and that the policies that allowed for privilege escalation would be the inherently permissive ones such as the full access policies.

Results

As previously mentioned the results of this research were not very shocking and pretty much fit into what was expected. There are 743 managed policies offered in AWS, out of that 743 only 36 allowed for privilege escalation, meaning that only 4.8% of the available managed polices allowed for privilege escalation. Most of the policies that allowed for privilege escalation were the inherently permissive policies. For example, most of the policies that gave a user full access to a particular service allowed for the potential of privilege escalation. Another important thing to understand about privilege escalation in AWS in general is that just because a policy allows for privilege escalation in theory does not mean it is possible in a given AWS environment. There are multiple methods of privilege escalation that involve the starting of a service and using the iam:PassRole call to pass a more permissive role to that service and then stealing the access keys, or performing an action such as adding a policy to your current account using that role. This is best shown by the following example.

I created a new user in AWS and attached the AWSMarketPlaceFullAccess policy to the user. I also attached a policy that I created named “Test” to it, this policy only has list access to IAM. I did this because not all of the policies below had access to list their own permissions using the IAM API. Not giving my test user list access to IAM would have made it more difficult to use Pacu to verify if a policy did in fact allow for privilege escalation. From an actual assessment standpoint, if permissions could not be enumerated they can be brute forced or discovered via other methods.

In the following set of screenshots, you will be able to see me run the Pacu module iam__privesc_scan. This module will enumerate an accounts permissions and attempt to escalate privileges. The module confirmed that the AWSMarketPlaceFullAccess policy was potentially able to escalate privileges by passing a more permissive role to an EC2 instance or to a new CloudFormation stack. In this example, I went with passing an instance profile to EC2. The role that I ran the EC2 instance was named “TestDeleteLater” and had the AdministratorAccess managed policy attached to it. To escalate privileges and obtain Administrator access, I added a call to IAM in the user data of the instance that will attach the AdministratorAccess policy to my test user. It is important to understand that if a role with an elevated set of permissions did not exist, privilege escalation would not have been possible in this scenario.

Running iam__privesc_scan Running privesc scan

Escalating privileges Escalating

Administrator Access Achieved Admin

The full list of AWS managed policies that allow for privilege escalation can be seen below.

AWSMarketplaceFullAccess

  1. PassingRoleToEC2
  2. PassingRoleToCloudFormation

AWSLambdaFullAccess

  1. PassExistingRoleToNewLambdaThenInvoke
  2. PassExistingRoleToNewLambdaThenTriggerWithExistingDynamo
  3. EditExistingLambdaFunctionWithRole

IAMFullAccess

  1. CreateNewPolicyVersion
  2. SetExistingDefaultPolicyVersion
  3. CreateAccessKey
  4. CreateLoginProfile
  5. UpdateLoginProfile
  6. AttachUserPolicy
  7. AttachGroupPolicy
  8. PutUserPolicy
  9. PutGroupPolicy
  10. AddUserToGroup

DatabaseAdministrator

  1. PassingRoleToNewLambdaFunctionAndTriggeringWithDynamo
  2. PassingRoleToDataPipeline
  3. PassExistingRoleToNewLambdaThenTriggerWithExistingDynamo

AWSSSOServiceRolePolicy

  1. AttachPolicyToRole
  2. CreateOrUpdateInlinePolicyForRole

AWSGlueServiceNotebookRole

  1. UpdatingExistingGlueDevEndpoint

AWSDataPipeline_PowerUser

  1. PassExistingRoleToNewDataPipeline

AWSCodeStarServiceRole

  1. CreateNewPolicyVersion
  2. SetDefaultPolicyVersion
  3. AttachPolicyToUser
  4. AttachPolicyToRole
  5. CreateOrUpdateInlinePolicyForRole
  6. CreateEC2WithExistingIP
  7. PassExistingRoleToNewCloudFormation
  8. PassExistingRoleToNewCodeStarProject
  9. CodeStarCreateProjectFromTemplate
  10. CodeStarCreateProjectThenAssociateTeamMember

AmazonDynamoDBFullAccess

  1. PassingRoleToNewLambdaFunctionAndTriggeringWithDynamo
  2. PassingRoleToDataPipeline
  3. PassExistingRoleToNewLambdaThenTriggerWithExistingDynamo

AWSRoboMakerServiceRolePolicy

  1. UpdatingCodeOfExistingLambdaFunction

AWSGlueServiceRole

  1. UpdateExistingGlueDevEndpoint

AWSBatchServiceRole

  1. CreateECSTaskWithRole
  2. CreateEC2WithExistingIP

AWSCodeStarFullAccess

  1. CodeStarCreateProjectFromTemplate
  2. CodeStarCreateProjectThenAssociateTeamMember

AWSDataPipeline_FullAccess

  1. PassExistingRoleToNewDataPipeline

AmazonElasticMapReduceFullAccess

  1. PassingRoleToCloudFormation
  2. CreateEC2WithExistingIP

AWSElasticBeanstalkFullAccess

  1. CreateEC2WithExistingIP
  2. RunECSTaskWithRole
  3. PassExistingRoleToNewCloudFormation

AmazonDynamoDBFullAccesswithDataPipeline

  1. CreateEC2WithExistingIP
  2. PassExistingRoleToNewLambdaThenInvoke
  3. PassExistingRoleToNewLambdaThenTriggerWithNewDynamo
  4. PassExistingRoleToNewLambdaThenTriggerWithExistingDynamo
  5. PassExistingRoleToNewDataPipeline
  6. EditExistingLambdaFunctionWithRole

DataScientist

  1. PassingRoleToCloudFormation

AWSOpsWorksCMServiceRole

  1. PassingRoleToCloudFormation
  2. CreateEC2WithExistingIP

AmazonECS_FullAccess

  1. PassingRoleToCloudFormation
  2. CreateTaskWIthTaskRole
  3. CreateEC2WithExistingIP

AmazonEC2ContainerServiceFullAccess

  1. PassingRoleToCloudFormation
  2. CreateEC2WithExistingIP
  3. CreateTaskWIthTaskRole

AWSGlueConsoleSageMakerNotebookFullAccess

  1. CreateEC2WithExistingIP
  2. PassingRoleToCloudFormation
  3. PassExistingRoleToNewGlueDevEndpoint
  4. UpdateExistingGlueDevEndpoint

AWSDeepLensServiceRolePolicy

  1. UpdatingCodeOfExistingLambdaFunction

AWSElasticBeanstalkService

  1. PassExistingRoleToNewCloudFormation
  2. CreateEC2WithExistingIP

AWSGlueConsoleFullAccess

  1. PassingRoleToCloudFormation
  2. PassExistingRoleToNewGlueDevEndpoint
  3. UpdateExistingGlueDevEndpoint
  4. CreateEC2WithExistingIP

AWSDeepRacerServiceRolePolicy

  1. PassingRoleToNewLambdaFunctionAndInvoking
  2. UpdatingCodeOfExistingLambdaFunction
  3. PassingRoleToCloudFormation

AWSServiceCatalogAdminFullAccess

  1. PassingRoleToCloudFormation

AWSDeepRacerCloudFormationAccessPolicy

  1. UpdatingCodeOfExistingLambdaFunction
  2. PassExistingRoleToNewCloudFormation

AmazonLaunchWizard_Fullaccess

  1. PassingRoleToNewLambdaFunctionAndInvoking
  2. PassingRoleToCloudFormation

AWSThinkboxAWSPortalAdminPolicy

  1. PassingRoleToCloudFormation
  2. CreateEC2WithExistingIP

AWSOpsWorksRegisterCLI_OnPremises

  1. CreateNewUserAccessKey
  2. AttachPolicyToUser
  3. AddUserToGroup

AWSThinkboxDeadlineResourceTrackerAdminPolicy

  1. PassingRoleToNewLambdaFunctionAndTriggeringWithDynamo
  2. PassingRoleToCloudFormation

AWSControlTowerServiceRolePolicy

  1. PassingRoleToCloudFormation

ServerMigration_ServiceRole

  1. PassingRoleToCloudFormation

AWSElasticBeanstalkRoleCore

  1. PassingRoleToCloudFormation
  2. CreateEC2WithExistingIP

AWSLambda_FullAccess

  1. PassExistingRoleToNewLambdaThenInvoke
  2. PassExistingRoleToNewLambdaThenTriggerWithExistingDynamo
  3. EditExistingLambdaFunctionWithRole