KMS Key Policy Privilege Escalation

Andreas Wittig – 31 Jan 2024

Encrypting data at rest is a widespread best practice on AWS. In 2019, Werner Vogels set the tone with his motivational slogan, “Dance like nobody’s watching. Encrypt like everyone is!”. AWS shipped the ability to encrypt data at rest for almost all its services. Many services use the AWS Key Management Service (KMS) to handle the keys for server-side encryption. KMS provides default keys, which are very simple to use, and customer-managed keys with an extra authorization layer.

Are you defining key policies to strictly restrict access to customer-managed keys? Then, the following will blow your mind. Under some circumstances, an IAM identity (user or role) can grant itself administrator access to any customer-managed key.

This is not an unknown security vulnerability. The procedured explained here is even mentioned in the AWS documentation.

KMS Key Policy Privilege Escalation

The story

Bob, the owner of an AWS account, is granted AdministratorAccess. He creates a customer-managed key and assigns the following key policy. He wants to ensure that no one else can delete or modify the key, so he only grants his own user administrator access to the key.

{
"Version": "2012-10-17",
"Statement":[{
"Sid": "Allow access for Key Administrators",
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::091140455148:user/bob"
]
},
"Action": [
"kms:Create*",
"kms:Describe*",
"kms:Enable*",
"kms:List*",
"kms:Put*",
"kms:Update*",
"kms:Revoke*",
"kms:Disable*",
"kms:Get*",
"kms:Delete*",
"kms:TagResource",
"kms:UntagResource",
"kms:ScheduleKeyDeletion",
"kms:CancelKeyDeletion"
],
"Resource": "*"
}]
}

Alice, a colleague of Bob’s, has AdministratorAccess to the same AWS account. However, due to the key policy, she is not able to delete or modify the customer-managed key created by Bob. Nevertheless, Alice found a way to delete the key anyway.

First, Alice deletes the IAM user arn:aws:iam::091140455148:user/bob, which is not an issue as iam:DeleteUser is granted by the AdministratorAccess policy.

Next, Alice updates the phone number of the AWS account with her mobile number. The AdministratorAccess policy grants her access to the account:PutContactInformation action to do so.

Afterwards, Alice contacts AWS support and tells the story that by mistake the customer-managed key is no longer accessible to any key administrator. She asks to reset the key policy. The AdministratorAccess policy grants her access to the required support:CreateCase action.

AWS verifies the key policy. Indeed, the key is not accessible to any key administrator.

Next, AWS updates the support case and asks to create a new IAM user named recovery, that shall be used to reset the key. Also, AWS provides a one-time password that will be used to verify the policy reset later.

Alice creates a new IAM user as described by AWS and asks to proceed with the policy reset by updating the support case. All she needs is access to iam:CreateUser granted by the AdministratorAccess policy.

A few hours later, AWS tries to verify that the request to reset the key policy is valid. To do so, AWS calls the number specified in the contact details of the AWS account.

And guess what? Alice answers the call. She confirms the reset of the key policy.

So, the process continues. AWS resets the key policy and grants the IAM user recovery administrator access to the customer-managed key.

Alice creates access keys for the IAM user recovery, which requires access to the iam:CreateAccessKey action.

Finally, Alice uses these access keys to schedule the customer-managed key for deletion.

The preconditions

Access to the following IAM actions is needed.

  • iam:DeleteUser to delete all IAM users listed as key administrators
  • iam:DeleteRole to delete all IAM roles listed as key administrators
  • account:PutContactInformation to update the contact information of the AWS account
  • support:CreateCase to create a support case to ask for a key policy reset
  • iam:CreateUser to create the IAM user needed for the key policy reset procedure
  • iam:CreateAccessKey to create credentials for the IAM user used during the key policy reset procedure

In addition, the key policy must not grant administrator access to any other existing IAM identity. In particular, the key policy must not contain the following statement, which delegates authorization entirely to IAM and is used by AWS as the default.

{
"Sid": "Enable IAM Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111122223333:root"
},
"Action": "kms:*",
"Resource": "*"
}

Last but not least, an AWS support plan is needed.

The mitigations

As an AWS customer, you could restrict access to account:PutContactInformation using service control policies (SCPs). Alternatively, you could avoid relying on key policies and completely delegate authorization to IAM.

AWS needs to find another way to deal with key policies. A half-baked procedure executed by AWS support is not a solution and undermines my trust in KMS. In my opinion, it should not be possible to reset key policies at all.

Andreas Wittig

Andreas Wittig

I’ve been building on AWS since 2012 together with my brother Michael. We are sharing our insights into all things AWS on cloudonaut and have written the book AWS in Action. Besides that, we’re currently working on bucketAV,HyperEnv for GitHub Actions, and marbot.

Here are the contact options for feedback and questions.