AWS - Nitro Enum

Apprenez le piratage AWS de zéro à héros avec htARTE (Expert en équipe rouge AWS de HackTricks)!

Autres façons de soutenir HackTricks :

Informations de base

AWS Nitro est une suite de technologies innovantes qui forment la plateforme sous-jacente des instances AWS EC2. Introduit par Amazon pour améliorer la sécurité, les performances et la fiabilité, Nitro exploite des composants matériels personnalisés et un hyperviseur léger. Il abstrait une grande partie de la fonctionnalité de virtualisation traditionnelle vers du matériel et des logiciels dédiés, minimisant la surface d'attaque et améliorant l'efficacité des ressources. En déchargeant les fonctions de virtualisation, Nitro permet aux instances EC2 de fournir des performances proches du métal nu, ce qui est particulièrement bénéfique pour les applications consommatrices de ressources. De plus, la puce de sécurité Nitro garantit spécifiquement la sécurité du matériel et du micrologiciel, renforçant davantage son architecture robuste.

Enclaves Nitro

Les enclaves Nitro AWS fournissent un environnement de calcul sécurisé et isolé au sein des instances Amazon EC2, spécialement conçu pour le traitement de données hautement sensibles. En exploitant le système Nitro AWS, ces enclaves garantissent une isolation et une sécurité robustes, idéales pour traiter des informations confidentielles telles que des données PII ou financières. Elles présentent un environnement minimaliste, réduisant considérablement le risque d'exposition des données. De plus, les enclaves Nitro prennent en charge l'attestation cryptographique, permettant aux utilisateurs de vérifier que seul le code autorisé s'exécute, ce qui est crucial pour respecter des normes strictes de conformité et de protection des données.

Les images d'enclaves Nitro sont exécutées à partir de l'intérieur des instances EC2 et vous ne pouvez pas voir depuis la console web AWS si une instance EC2 exécute des images dans une enclave Nitro ou non.

Installation de l'interface en ligne de commande des enclaves Nitro

Suivez toutes les instructions du document. Cependant, voici les plus importantes :

# Install tools
sudo amazon-linux-extras install aws-nitro-enclaves-cli -y
sudo yum install aws-nitro-enclaves-cli-devel -y

# Config perms
sudo usermod -aG ne $USER
sudo usermod -aG docker $USER

# Check installation
nitro-cli --version

# Start and enable the Nitro Enclaves allocator service.
sudo systemctl start nitro-enclaves-allocator.service && sudo systemctl enable nitro-enclaves-allocator.service

Images de l'Enclave Nitro

Les images que vous pouvez exécuter dans l'Enclave Nitro sont basées sur des images docker, vous pouvez donc créer vos propres images d'Enclave Nitro à partir d'images docker telles que :

# You need to have the docker image accesible in your running local registry
# Or indicate the full docker image URL to access the image
nitro-cli build-enclave --docker-uri <docker-img>:<tag> --output-file nitro-img.eif

Comme vous pouvez le voir, les images Nitro Enclave utilisent l'extension eif (Enclave Image File).

La sortie ressemblera à :

Using the locally available Docker image...
Enclave Image successfully created.
{
"Measurements": {
"HashAlgorithm": "Sha384 { ... }",
"PCR0": "e199261541a944a93129a52a8909d29435dd89e31299b59c371158fc9ab3017d9c450b0a580a487e330b4ac691943284",
"PCR1": "bcdf05fefccaa8e55bf2c8d6dee9e79bbff31e34bf28a99aa19e6b29c37ee80b214a414b7607236edf26fcb78654e63f",
"PCR2": "2e1fca1dbb84622ec141557dfa971b4f8ea2127031b264136a20278c43d1bba6c75fea286cd4de9f00450b6a8db0e6d3"
}
}

Exécuter une image

Selon la documentation, pour exécuter une image d'enclave, vous devez lui attribuer une mémoire d'au moins 4 fois la taille du fichier eif. Il est possible de configurer les ressources par défaut à lui attribuer dans le fichier.

/etc/nitro_enclaves/allocator.yaml

N'oubliez pas que vous devez réserver des ressources pour l'instance EC2 parente également !

Après avoir identifié les ressources à attribuer à une image et même avoir modifié le fichier de configuration, il est possible d'exécuter une image d'enclave avec :

# Restart the service so the new default values apply
sudo systemctl start nitro-enclaves-allocator.service && sudo systemctl enable nitro-enclaves-allocator.service

# Indicate the CPUs and memory to give
nitro-cli run-enclave --cpu-count 2 --memory 3072 --eif-path hello.eif --debug-mode --enclave-cid 16

Énumérer les Enclaves

Si vous compromettez un hôte EC2, il est possible d'obtenir une liste des images d'enclave en cours d'exécution avec :

nitro-cli describe-enclaves

Il n'est pas possible d'obtenir un shell à l'intérieur d'une image d'enclave en cours d'exécution car c'est le but principal de l'enclave, cependant, si vous avez utilisé le paramètre --debug-mode, il est possible d'obtenir la sortie standard avec :

ENCLAVE_ID=$(nitro-cli describe-enclaves | jq -r ".[0].EnclaveID")
nitro-cli console --enclave-id ${ENCLAVE_ID}

Terminer les Enclaves

Si un attaquant compromet une instance EC2, par défaut, il ne pourra pas obtenir un shell à l'intérieur, mais il pourra les terminer avec :

nitro-cli terminate-enclave --enclave-id ${ENCLAVE_ID}

Vsock

La seule façon de communiquer avec une enclave exécutant une image est d'utiliser vsocks.

Virtual Socket (vsock) est une famille de sockets dans Linux spécifiquement conçue pour faciliter la communication entre les machines virtuelles (VMs) et leurs hyperviseurs, ou entre les VMs eux-mêmes. Vsock permet une communication bidirectionnelle efficace sans dépendre de la pile réseau de l'hôte. Cela permet aux VMs de communiquer même sans configurations réseau, en utilisant un identifiant de contexte (CID) sur 32 bits et des numéros de port pour identifier et gérer les connexions. L'API vsock prend en charge à la fois les types de sockets de flux et de datagramme, similaires à TCP et UDP, offrant un outil polyvalent pour les applications au niveau utilisateur dans des environnements virtuels.

Par conséquent, une adresse vsock ressemble à ceci : <CID>:<Port>

Pour trouver les CIDs des images exécutant des enclaves, vous pouvez simplement exécuter la commande suivante et obtenir le EnclaveCID :

nitro-cli describe-enclaves

[
{
"EnclaveName": "secure-channel-example",
"EnclaveID": "i-0bc274f83ade02a62-enc18ef3d09c886748",
"ProcessID": 10131,
    "EnclaveCID": 16,
    "NumberOfCPUs": 2,
"CPUIDs": [
1,
3
],
"MemoryMiB": 1024,
"State": "RUNNING",
"Flags": "DEBUG_MODE",
"Measurements": {
"HashAlgorithm": "Sha384 { ... }",
"PCR0": "e199261541a944a93129a52a8909d29435dd89e31299b59c371158fc9ab3017d9c450b0a580a487e330b4ac691943284",
"PCR1": "bcdf05fefccaa8e55bf2c8d6dee9e79bbff31e34bf28a99aa19e6b29c37ee80b214a414b7607236edf26fcb78654e63f",
"PCR2": "2e1fca1dbb84622ec141557dfa971b4f8ea2127031b264136a20278c43d1bba6c75fea286cd4de9f00450b6a8db0e6d3"
}
}
]

Notez que depuis l'hôte, il n'y a aucun moyen de savoir si un CID expose un port ! Sauf en utilisant un scanner de ports vsock comme https://github.com/carlospolop/Vsock-scanner.

Serveur/Écouteur Vsock

Voici quelques exemples :

Écouteur Python Simple

```python #!/usr/bin/env python3

From

https://medium.com/@F.DL/understanding-vsock-684016cf0eb0

import socket

CID = socket.VMADDR_CID_HOST PORT = 9999

s = socket.socket(socket.AF_VSOCK, socket.SOCK_STREAM) s.bind((CID, PORT)) s.listen() (conn, (remote_cid, remote_port)) = s.accept()

print(f"Connection opened by cid={remote_cid} port={remote_port}")

while True: buf = conn.recv(64) if not buf: break

print(f"Received bytes: {buf}")

</details>
```bash
# Using socat
socat VSOCK-LISTEN:<port>,fork EXEC:"echo Hello from server!"

Client Vsock

Exemples :

Dernière mise à jour