# GCP - KMS Privesc

{{#include ../../../banners/hacktricks-training.md}}

## KMS

Info about KMS:

{{#ref}}
../gcp-services/gcp-kms-enum.md
{{#endref}}

Note that in KMS the **permission** are not only **inherited** from Orgs, Folders and Projects but also from **Keyrings**.

### `cloudkms.cryptoKeyVersions.useToDecrypt`

You can use this permission to **decrypt information with the key** you have this permission over.

<details><summary>Decrypt data using KMS key</summary>

```bash
gcloud kms decrypt \
    --location=[LOCATION] \
    --keyring=[KEYRING_NAME] \
    --key=[KEY_NAME] \
    --version=[KEY_VERSION] \
    --ciphertext-file=[ENCRYPTED_FILE_PATH] \
    --plaintext-file=[DECRYPTED_FILE_PATH]
```

</details>

### `cloudkms.cryptoKeys.setIamPolicy`

An attacker with this permission could **give himself permissions** to use the key to decrypt information.

<details><summary>Grant yourself KMS decrypter role</summary>

```bash
gcloud kms keys add-iam-policy-binding [KEY_NAME] \
    --location [LOCATION] \
    --keyring [KEYRING_NAME] \
    --member [MEMBER] \
    --role roles/cloudkms.cryptoKeyDecrypter
```

</details>

### `cloudkms.cryptoKeyVersions.useToDecryptViaDelegation`

Here's a conceptual breakdown of how this delegation works:

1. **Service Account A** has direct access to decrypt using a specific key in KMS.
2. **Service Account B** is granted the `useToDecryptViaDelegation` permission. This allows it to request KMS to decrypt data on behalf of Service Account A.

The usage of this **permission is implicit in the way that the KMS service checks permissions** when a decryption request is made.

When you make a standard decryption request using the Google Cloud KMS API (in Python or another language), the service **checks whether the requesting service account has the necessary permissions**. If the request is made by a service account with the **`useToDecryptViaDelegation`** permission, KMS verifies whether this **account is allowed to request decryption on behalf of the entity that owns the key**.

#### Setting Up for Delegation

1. **Define the Custom Role**: Create a YAML file (e.g., `custom_role.yaml`) that defines the custom role. This file should include the `cloudkms.cryptoKeyVersions.useToDecryptViaDelegation` permission. Here's an example of what this file might look like:

<details><summary>Custom role YAML definition</summary>

```yaml
title: "KMS Decryption via Delegation"
description: "Allows decryption via delegation"
stage: "GA"
includedPermissions:
  - "cloudkms.cryptoKeyVersions.useToDecryptViaDelegation"
```

</details>

2. **Create the Custom Role Using the gcloud CLI**: Use the following command to create the custom role in your Google Cloud project:

<details><summary>Create custom KMS role</summary>

```bash
gcloud iam roles create kms_decryptor_via_delegation --project [YOUR_PROJECT_ID] --file custom_role.yaml
```

Replace `[YOUR_PROJECT_ID]` with your Google Cloud project ID.

</details>

3. **Grant the Custom Role to a Service Account**: Assign your custom role to a service account that will be using this permission. Use the following command:

<details><summary>Grant custom role to service account</summary>

```bash
# Give this permission to the service account to impersonate
gcloud projects add-iam-policy-binding [PROJECT_ID] \
    --member "serviceAccount:[SERVICE_ACCOUNT_B_EMAIL]" \
    --role "projects/[PROJECT_ID]/roles/[CUSTOM_ROLE_ID]"

# Give this permission over the project to be able to impersonate any SA
gcloud projects add-iam-policy-binding [YOUR_PROJECT_ID] \
    --member="serviceAccount:[SERVICE_ACCOUNT_EMAIL]" \
    --role="projects/[YOUR_PROJECT_ID]/roles/kms_decryptor_via_delegation"
```

Replace `[YOUR_PROJECT_ID]` and `[SERVICE_ACCOUNT_EMAIL]` with your project ID and the email of the service account, respectively.

</details>

{{#include ../../../banners/hacktricks-training.md}}



