From 40951cb99bf732aa292e6487a2bf283d913876bb Mon Sep 17 00:00:00 2001 From: HackTricks News Bot Date: Wed, 5 Aug 2026 19:41:20 +0000 Subject: [PATCH] =?UTF-8?q?Add=20content=20from:=20A=20Few=20Notes=20on=20?= =?UTF-8?q?AWS=20Nitro=20Enclaves=E2=80=93KMS=20Integration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../aws-kms-post-exploitation/README.md | 58 ++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-kms-post-exploitation/README.md b/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-kms-post-exploitation/README.md index 9647d50efb..3fab96b731 100644 --- a/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-kms-post-exploitation/README.md +++ b/src/pentesting-cloud/aws-security/aws-post-exploitation/aws-kms-post-exploitation/README.md @@ -2,6 +2,8 @@ {{#include ../../../../banners/hacktricks-training.md}} + + ## KMS For more information check: @@ -178,6 +180,52 @@ aws kms derive-shared-secret \ --key-agreement-algorithm ``` + +### Nitro Enclaves–KMS integration attacks + +For PCR and attestation background, check: + +{{#ref}} +../../aws-services/aws-ec2-ebs-elb-ssm-vpc-and-vpn-enum/aws-nitro-enum.md +{{#endref}} + +Attested Nitro requests only change **authorization** and how AWS KMS returns **plaintext** material. `Decrypt`, `DeriveSharedSecret`, `GenerateDataKey`, `GenerateDataKeyPair`, and `GenerateRandom` can receive a `Recipient` attestation document containing the enclave public key; AWS KMS validates the attestation and encrypts the sensitive response to that key. `Encrypt` does **not** get this attested-response flow, so direct CMK encryption is a common design smell when enclave identity is expected to gate the operation.[1][2][3][5] + +- **Omit `Recipient` / weak PCR policy enforcement:** If the application accepts KMS requests or responses without `Recipient`, or the key policy does not require the expected PCRs, the enclave loses the binding between the measured enclave, KMS authorization, and the response-encryption key. Look for designs where the parent EC2 instance or another broker can call KMS without enclave attestation and still obtain usable output.[1][2][3][5] +- **Wrapped-key / shared-secret substitution:** A valid `CiphertextBlob`, encrypted private key, or ECDH shared-secret blob stored outside the enclave can often be swapped with another blob produced under the same CMK. Successful `Decrypt` only proves that the blob was encrypted under an allowed KMS key, not that it belongs to the expected tenant, object, or protocol step.[1] + +Bind every wrapped value to trusted state with `EncryptionContext`, and explicitly send the expected `KeyId` on `Decrypt`.[1][4] + +```python +context = { + "tenant": tenant_id, + "object": record_id, + "purpose": "db-field-encryption", + "version": version, +} +kms.generate_data_key(KeyId=EXPECTED_CMK_ARN, + EncryptionContext=context, + Recipient=recipient) +kms.decrypt(CiphertextBlob=wrapped_key, + KeyId=EXPECTED_CMK_ARN, + EncryptionContext=context, + Recipient=recipient) +``` + +- **Ciphertext + context pair swapping:** `EncryptionContext` only helps if at least one security-critical field comes from trusted enclave state or attested configuration. If the attacker controls both the wrapped blob and the entire context, they can replay a matching pair or mint new valid pairs anywhere they still have `kms:Encrypt` or `kms:GenerateDataKey*` on the same CMK.[1][4] +- **Application-ciphertext relocation:** Protecting the wrapped data key is not enough. Data encrypted locally with that key also needs AEAD-associated data bound to tenant, object, record type, location, purpose, and version; otherwise valid ciphertext can be moved between records or semantic roles.[1][4] + +Bind locally encrypted data to the same trusted identifiers used in the KMS context, and prefer formats with key commitment.[1] + +```python +aad = encode(tenant_id, record_id, record_type, purpose, version) +ciphertext = aead_encrypt(data_key, nonce, plaintext, aad) +plaintext = aead_decrypt(data_key, nonce, ciphertext, aad) +``` + +- **CMK / alias / account / Region confusion:** If an attacker can influence the `KeyId`, alias, IAM role, account, or Region used by the enclave, they may redirect the flow to an unintended but still valid key. Hardcode the full CMK ARN, avoid mutable aliases, explicitly pass `KeyId` to `Decrypt`, and verify that the returned `KeyId` matches the expected ARN.[1] +- **Replay / rollback / metadata confusion:** Old wrapped keys, ciphertexts, and responses can remain perfectly valid and still roll the enclave back to stale state. Enforce freshness with authenticated versions, counters, epochs, or nonces, and do not trust external metadata or defaults for key type, algorithm, or key usage.[1] + ### Impersonation via kms:Sign With the `kms:Sign` permission, an actor can use a KMS-stored CMK to cryptographically sign data without exposing the private key, producing valid signatures that can enable impersonation or authorize malicious actions. @@ -204,5 +252,13 @@ aws kms update-custom-key-store --custom-key-store-id --ne
-{{#include ../../../../banners/hacktricks-training.md}} +## References + +- [1] [A few notes on AWS Nitro Enclaves: KMS integration - The Trail of Bits Blog](https://blog.trailofbits.com/2026/08/05/a-few-notes-on-aws-nitro-enclaves-kms-integration/) +- [2] [Cryptographic attestation support in AWS KMS - AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/cryptographic-attestation.html) +- [3] [RecipientInfo - AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/APIReference/API_RecipientInfo.html) +- [4] [Encryption context - AWS Key Management Service](https://docs.aws.amazon.com/kms/latest/developerguide/encrypt_context.html) +- [5] [Cryptographic attestation - AWS Nitro Enclaves](https://docs.aws.amazon.com/enclaves/latest/user/set-up-attestation.html) + +{{#include ../../../../banners/hacktricks-training.md}}