AWS - Nitro Enum

Support HackTricks

Basic Information

AWS Nitro to zestaw innowacyjnych technologii, które stanowią podstawową platformę dla instancji AWS EC2. Wprowadzony przez Amazon w celu zwiększenia bezpieczeństwa, wydajności i niezawodności, Nitro wykorzystuje niestandardowe komponenty sprzętowe i lekką warstwę hipernadzoru. Abstrakcyjnie przenosi wiele tradycyjnych funkcji wirtualizacji na dedykowany sprzęt i oprogramowanie, minimalizując powierzchnię ataku i poprawiając efektywność zasobów. Przez odciążenie funkcji wirtualizacji, Nitro pozwala instancjom EC2 dostarczać wydajność bliską wydajności sprzętowej, co jest szczególnie korzystne dla aplikacji wymagających dużych zasobów. Dodatkowo, Nitro Security Chip zapewnia bezpieczeństwo sprzętu i oprogramowania układowego, co dodatkowo wzmacnia jego solidną architekturę.

Nitro Enclaves

AWS Nitro Enclaves zapewniają bezpieczne, izolowane środowisko obliczeniowe w instancjach Amazon EC2, zaprojektowane specjalnie do przetwarzania wysoce wrażliwych danych. Wykorzystując system AWS Nitro, te enklawy zapewniają solidną izolację i bezpieczeństwo, idealne do obsługi poufnych informacji, takich jak PII lub dane finansowe. Oferują minimalistyczne środowisko, znacznie redukując ryzyko ujawnienia danych. Dodatkowo, Nitro Enclaves wspierają kryptograficzną attestację, umożliwiając użytkownikom weryfikację, że tylko autoryzowany kod jest uruchamiany, co jest kluczowe dla utrzymania ścisłej zgodności i standardów ochrony danych.

Obrazy Nitro Enclave są uruchamiane z wnętrza instancji EC2 i nie można zobaczyć w konsoli internetowej AWS, czy instancje EC2 uruchamiają obrazy w Nitro Enclave, czy nie.

Nitro Enclave CLI installation

Follow the all instructions from the documentation. However, these are the most important ones:

# 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

Nitro Enclave Images

Obrazy, które możesz uruchomić w Nitro Enclave, są oparte na obrazach docker, więc możesz tworzyć swoje obrazy Nitro Enclave z obrazów docker, takich jak:

# 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

Jak widać, obrazy Nitro Enclave używają rozszerzenia eif (Enclave Image File).

Wynik będzie wyglądał podobnie do:

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

Uruchom obraz

Zgodnie z dokumentacją, aby uruchomić obraz enklawy, musisz przypisać mu pamięć o co najmniej 4-krotności rozmiaru pliku eif. Możliwe jest skonfigurowanie domyślnych zasobów, które mu przydzielisz w pliku.

/etc/nitro_enclaves/allocator.yaml

Zawsze pamiętaj, że musisz zarezerwować pewne zasoby dla rodzica instancji EC2!

Po poznaniu zasobów, które należy przydzielić obrazowi, a nawet po zmodyfikowaniu pliku konfiguracyjnego, możliwe jest uruchomienie obrazu enklawy za pomocą:

# 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

Enumeracja Enklaw

Jeśli skompromitujesz hosta EC2, możliwe jest uzyskanie listy działających obrazów enklaw za pomocą:

nitro-cli describe-enclaves

Nie jest możliwe uzyskanie powłoki wewnątrz działającego obrazu enclave, ponieważ to jest główny cel enclave, jednak jeśli użyjesz parametru --debug-mode, możliwe jest uzyskanie stdout za pomocą:

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

Terminate Enclaves

Jeśli atakujący skompromituje instancję EC2, domyślnie nie będzie w stanie uzyskać powłoki wewnątrz nich, ale będzie mógł je zakończyć za pomocą:

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

Vsocks

Jedynym sposobem na komunikację z enklawą uruchamiającą obraz jest użycie vsocks.

Virtual Socket (vsock) to rodzina gniazd w systemie Linux, zaprojektowana specjalnie w celu ułatwienia komunikacji między maszynami wirtualnymi (VM) a ich hypervisorami, lub między VM sami. Vsock umożliwia efektywną, dwukierunkową komunikację bez polegania na stosie sieciowym hosta. Umożliwia to VM komunikację nawet bez konfiguracji sieci, używając 32-bitowego identyfikatora kontekstu (CID) i numerów portów do identyfikacji i zarządzania połączeniami. API vsock obsługuje zarówno typy gniazd strumieniowych, jak i datagramowych, podobnie jak TCP i UDP, co zapewnia wszechstronne narzędzie dla aplikacji na poziomie użytkownika w wirtualnych środowiskach.

Dlatego adres vsock wygląda tak: <CID>:<Port>

Aby znaleźć CIDs obrazów uruchamiających enklawę, możesz po prostu wykonać następujące polecenie i uzyskać 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"
}
}
]

Zauważ, że z hosta nie ma sposobu, aby wiedzieć, czy CID eksponuje jakiś port! Chyba że używasz jakiegoś skanera portów vsock, takiego jak https://github.com/carlospolop/Vsock-scanner.

Vsock Server/Listener

Znajdź tutaj kilka przykładów:

Prosty nasłuchiwacz w Pythonie

```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!"

Klient Vsock

Przykłady:

Last updated