AWS - Nitro Enum

Naucz się hakować AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!

Inne sposoby wsparcia HackTricks:

Podstawowe informacje

AWS Nitro to zestaw innowacyjnych technologii, które stanowią podstawową platformę dla instancji AWS EC2. Wprowadzony przez Amazon w celu poprawy bezpieczeństwa, wydajności i niezawodności, Nitro wykorzystuje dedykowane komponenty sprzętowe i lekki hipernadzorca. Abstrahuje wiele tradycyjnych funkcji wirtualizacji do dedykowanego sprzętu i oprogramowania, minimalizując powierzchnię ataku i poprawiając efektywność zasobów. Poprzez przeniesienie funkcji wirtualizacji, Nitro pozwala instancjom EC2 osiągać wydajność zbliżoną do metalu, co jest szczególnie korzystne dla aplikacji wymagających dużych zasobów. Dodatkowo, specjalny układ zabezpieczeń Nitro zapewnia bezpieczeństwo sprzętu i oprogramowania, dodatkowo umacniając jego solidną architekturę.

Komory Nitro

AWS Nitro Enclaves zapewniają bezpieczne, izolowane środowisko obliczeniowe w instancjach Amazon EC2, specjalnie zaprojektowane do przetwarzania bardzo wrażliwych danych. Wykorzystując System AWS Nitro, te komory zapewniają solidną izolację i bezpieczeństwo, idealne do obsługi poufnych informacji takich jak PII czy dane finansowe. Charakteryzują się minimalistycznym środowiskiem, znacząco zmniejszając ryzyko ujawnienia danych. Dodatkowo, komory Nitro obsługują atestację kryptograficzną, pozwalając użytkownikom zweryfikować, że uruchamiany jest tylko autoryzowany kod, co jest kluczowe dla zachowania surowych standardów zgodności i ochrony danych.

Obrazy komór Nitro są uruchamiane wewnątrz instancji EC2 i nie można ich zobaczyć w konsoli internetowej AWS, czy instancja EC2 uruchamia obrazy w komorze Nitro, czy nie.

Instalacja interfejsu wiersza poleceń komory Nitro

Postępuj zgodnie ze wszystkimi instrukcjami z dokumentacji. Jednakże, oto najważniejsze:

# 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

Obrazy Enklawy Nitro

Obrazy, które można uruchamiać w Enklawie Nitro, są oparte na obrazach dockerowych, więc możesz tworzyć swoje obrazy Enklawy Nitro z obrazów dockerowych, 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).

Wyjście będzie wyglądać podobnie jak:

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ęć co najmniej 4 razy większą niż rozmiar pliku eif. Możliwe jest skonfigurowanie domyślnych zasobów do przypisania w pliku.

/etc/nitro_enclaves/allocator.yaml

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

Po poznaniu zasobów do przypisania obrazowi i nawet po zmodyfikowaniu pliku konfiguracyjnego można uruchomić obraz 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

Wyliczanie Enklaw

Jeśli przejmiesz hosta EC2, możesz uzyskać listę uruchomionych obrazów enklaw za pomocą:

nitro-cli describe-enclaves

Nie jest możliwe uzyskanie powłoki wewnątrz działającego obrazu enklawy, ponieważ to główne przeznaczenie enklawy, jednakże, jeśli użyto parametru --debug-mode, możliwe jest uzyskanie jego stdout za pomocą:

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

Zakończ enklawy

Jeśli atakujący przejmie instancję EC2, domyślnie nie będzie mógł uzyskać do nich dostępu za pomocą powłoki, ale będzie mógł je zakończyć przy użyciu:

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

Vsock

Jedynym sposobem komunikacji z uruchomionym obrazem enklawy jest użycie vsocks.

Wirtualny gniazdek (vsock) to rodzina gniazdek w systemie Linux, specjalnie zaprojektowana do ułatwiania komunikacji między maszynami wirtualnymi (VM) a ich hipernadzorcami, lub między samymi VM sobą. Vsock umożliwia efektywną, dwukierunkową komunikację bez polegania na stosie sieciowym hosta. Dzięki temu maszyny wirtualne mogą komunikować się nawet bez konfiguracji sieciowej, korzystając z 32-bitowego identyfikatora kontekstu (CID) i numerów portów do identyfikacji i zarządzania połączeniami. Interfejs API vsock obsługuje zarówno gniazdka strumieniowe, jak i datagramowe, podobnie jak TCP i UDP, zapewniając wszechstronne narzędzie dla aplikacji na poziomie użytkownika w środowiskach wirtualnych.

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

Aby znaleźć CIDs uruchomionych obrazów enklawy, wystarczy 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 dowiedzieć się, czy CID ujawnia jakikolwiek port! Chyba że użyjesz jakiegoś skanera portów vsock, takiego jak https://github.com/carlospolop/Vsock-scanner.

Serwer/odbiornik Vsock

Oto kilka przykładów:

Prosty Słuchacz 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}")

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

Klient Vsock

Przykłady:

Last updated