# GCP - KMS Privesc

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

## KMS

KMS に関する情報:

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

KMS では、**権限**は組織、フォルダ、プロジェクトからだけでなく、**Keyrings** からも**継承されます**。

### `cloudkms.cryptoKeyVersions.useToDecrypt`

この権限があると、対象のキーを使って**情報を復号する**ことができます。

<details><summary>KMSキーを使ってデータを復号する</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`

この権限を持つ攻撃者は、鍵を使用して情報を復号する権限を**自分に付与する**ことができます。

<details><summary>自分に 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`

この委任がどのように機能するかの概念的な内訳は次の通りです:

1. **サービスアカウントA** は KMS の特定のキーを使って復号する直接的なアクセス権を持っています。
2. **サービスアカウントB** に `useToDecryptViaDelegation` 権限が付与されます。これによりサービスアカウントB は、サービスアカウントA に代わって KMS にデータの復号をリクエストできます。

この **権限の使用は、復号リクエスト時に KMS サービスが権限をチェックする方法に暗黙的に組み込まれています**。

Google Cloud KMS API（Python や他の言語）を使って標準的な復号リクエストを行うと、サービスは **リクエスト元のサービスアカウントが必要な権限を持っているかをチェックします**。もしそのリクエストが `useToDecryptViaDelegation` を持つサービスアカウントによって行われた場合、KMS はこの **アカウントがキーの所有者に代わって復号をリクエストすることを許可されているか** を検証します。

#### 委任の設定

1. **カスタムロールの定義**: `custom_role.yaml` などの YAML ファイルを作成し、カスタムロールを定義します。このファイルには `cloudkms.cryptoKeyVersions.useToDecryptViaDelegation` 権限を含める必要があります。以下はこのファイルの例です:

<details><summary>カスタムロール YAML 定義</summary>
```yaml
title: "KMS Decryption via Delegation"
description: "Allows decryption via delegation"
stage: "GA"
includedPermissions:
- "cloudkms.cryptoKeyVersions.useToDecryptViaDelegation"
```
</details>

2. **gcloud CLI を使用してカスタム ロールを作成する**: 次のコマンドを使用して、Google Cloud プロジェクトにカスタム ロールを作成します:

<details><summary>カスタム KMS ロールを作成</summary>
```bash
gcloud iam roles create kms_decryptor_via_delegation --project [YOUR_PROJECT_ID] --file custom_role.yaml
```
[YOUR_PROJECT_ID] をあなたの Google Cloud プロジェクト ID に置き換えてください。

</details>

3. **Grant the Custom Role to a Service Account**: このカスタムロールをこの権限を使用する service account に割り当てます。次のコマンドを使用してください:

<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"
```
`[YOUR_PROJECT_ID]` と `[SERVICE_ACCOUNT_EMAIL]` をそれぞれプロジェクトIDとサービスアカウントのメールアドレスに置き換えてください。

</details>

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