AWS - Nitro Enum

Aprenda hacking AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!

Outras maneiras de apoiar o HackTricks:

Informações Básicas

O AWS Nitro é um conjunto de tecnologias inovadoras que formam a plataforma subjacente para as instâncias AWS EC2. Introduzido pela Amazon para aumentar a segurança, desempenho e confiabilidade, o Nitro aproveita componentes de hardware personalizados e um hipervisor leve. Ele abstrai grande parte da funcionalidade de virtualização tradicional para hardware e software dedicados, minimizando a superfície de ataque e melhorando a eficiência de recursos. Ao descarregar funções de virtualização, o Nitro permite que as instâncias EC2 ofereçam desempenho quase bare-metal, tornando-o particularmente benéfico para aplicativos intensivos em recursos. Além disso, o Chip de Segurança Nitro garante especificamente a segurança do hardware e firmware, solidificando ainda mais sua arquitetura robusta.

Nitro Enclaves

AWS Nitro Enclaves fornece um ambiente de computação seguro e isolado dentro das instâncias Amazon EC2, projetado especificamente para processar dados altamente sensíveis. Aproveitando o Sistema AWS Nitro, esses enclaves garantem isolamento e segurança robustos, ideais para lidar com informações confidenciais como PII ou registros financeiros. Eles apresentam um ambiente minimalista, reduzindo significativamente o risco de exposição de dados. Além disso, os Nitro Enclaves suportam atestação criptográfica, permitindo que os usuários verifiquem que apenas o código autorizado está em execução, crucial para manter padrões rigorosos de conformidade e proteção de dados.

As imagens do Nitro Enclave são executadas de dentro das instâncias EC2 e você não pode ver no console da web da AWS se uma instância EC2 está executando imagens em Nitro Enclave ou não.

Instalação do CLI do Nitro Enclave

Siga todas as instruções da documentação. No entanto, estas são as mais 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

Imagens do Nitro Enclave

As imagens que você pode executar no Nitro Enclave são baseadas em imagens docker, então você pode criar suas imagens do Nitro Enclave a partir de imagens docker como:

# 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

Como você pode ver, as imagens do Nitro Enclave usam a extensão eif (Enclave Image File).

A saída será semelhante a:

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

Executar uma Imagem

Conforme a documentação, para executar uma imagem de enclave, você precisa atribuir a ela uma memória de pelo menos 4 vezes o tamanho do arquivo eif. É possível configurar os recursos padrão a serem fornecidos no arquivo.

/etc/nitro_enclaves/allocator.yaml

Lembre-se sempre de que você precisa reservar alguns recursos para a instância EC2 pai também!

Depois de saber os recursos a serem fornecidos para uma imagem e até mesmo ter modificado o arquivo de configuração, é possível executar uma imagem de enclave com:

# 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

Enumerar Enclaves

Se você comprometer um host EC2, é possível obter uma lista de imagens de enclaves em execução com:

nitro-cli describe-enclaves

Não é possível obter um shell dentro de uma imagem de enclave em execução porque esse é o principal objetivo do enclave, no entanto, se você usar o parâmetro --debug-mode, é possível obter o stdout com:

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

Terminar Enclaves

Se um atacante comprometer uma instância EC2, por padrão ele não poderá obter um shell dentro delas, mas ele poderá terminá-las com:

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

Vsock

A única maneira de comunicar com uma enclave em execução é usando vsocks.

Virtual Socket (vsock) é uma família de sockets no Linux projetada especificamente para facilitar a comunicação entre máquinas virtuais (VMs) e seus hipervisores, ou entre as próprias VMs. Vsock permite uma comunicação bidirecional eficiente, sem depender do stack de rede do host. Isso torna possível para as VMs se comunicarem mesmo sem configurações de rede, usando um ID de Contexto (CID) de 32 bits e números de porta para identificar e gerenciar conexões. A API vsock suporta tanto tipos de sockets de fluxo quanto de datagrama, semelhante ao TCP e UDP, fornecendo uma ferramenta versátil para aplicações de nível de usuário em ambientes virtuais.

Portanto, um endereço vsock se parece com isso: <CID>:<Port>

Para encontrar os CIDs das enclaves em execução, você pode simplesmente executar o seguinte comando e obter o 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"
}
}
]

Observe que a partir do host não há como saber se um CID está expondo alguma porta! A menos que esteja usando algum scanner de porta vsock como https://github.com/carlospolop/Vsock-scanner.

Servidor/Listener Vsock

Aqui estão alguns exemplos:

Listener Python Simples

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

Cliente Vsock

Exemplos:

Última actualización