【技术解读】【WebSec】My $20,000 S3 bug that leaked everyone’s attachments - S3 bucket misconfig of pre-signed URLs
前言
视频地址:https://www.youtube.com/watch?v=MBQJJ3jfJ8k&t=1s
youtube上bug bounty方向的知名博主 @BugBountyReportsExplained 在一次bug bounty项目中,发现了一个通过S3桶文件的越权访问漏洞,获得了2w刀赏金。
他参考的文章:
https://labs.detectify.com/writeups/bypassing-and-exploiting-bucket-upload-policies-and-signed-urls/
该参考文章的作者其实在2018年OWASP的会议上作了该议题的分享:
- 议题PPT:https://speakerdeck.com/fransrosen/owasp-appseceu-2018-attacking-modern-web-technologies?slide=44
- 议题视频:https://www.youtube.com/watch?v=oJCCOnF25JU
其实@BugBountyReportsExplained之前有发视频谈到参考文章中的技术点:
https://www.youtube.com/watch?v=G7Pre3Y46Fs
存在漏洞的功能
头像上传功能。服务端会将用户上传的头像图片上传到S3桶。
漏洞关键点
作者发现头像图片文件和其它用户的敏感信息是保存在同一个桶中,所以一旦存在越权访问漏洞,则影响很大,bounty多多的。
在用户与s3桶文件直接交互(HTTP/HTTPS)进行文件读写的场景,为了防止不同用户间的文件的越权访问,AWS S3提供了一种pre-signed URLs的机制,即s3文件的url中会带有签名。
业务流程关键数据包如下:
(1) 对服务端发起请求,获取S3上传路径:
POST /api/get-s3-url HTTP/1.1
Host: target.com
...
fname=avatar.png
服务端返回s3文件的的pre-signed URL,这个pre-signed URL会告诉你可以上传的文件位置(这里假设桶名为bucket
,文件保存为:0a2f...png
,这个文件名一般是一个hash值):
HTTP/1.1 200 OK
...
s3.amazonaws.com/bucket/0a2f...png?X-Amz-Signature=1f5a...b766
(2) 直接与S3服务交互,上传文件到刚刚返回的文件位置(桶名bucket
,文件名:0a2f...png
):
PUT /bucket/0a2f...png HTTP/1.1
Host: s3.amazonaws.com
...
...<文件内容>...
(3) 对服务发起请求,确认使用该S3文件(在S3桶中名为:0a2f...png
)作为头像:
POST /api/save-avatar HTTP/1.1
Host: target.com
...
fname=0a2f...png
通过这3步,便能完成用户头像的上传功能。
此时作者发现查看用户profile页面的html内容,发现头像位置的img
标签中,填充了头像图片的S3 pre-signed URL,大致如下:
<div id="login">greg</div>
<div>
<img src="https://s3.amazonaws.com/bucket/0a2f...png?X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Algorithm=AWS4-HMAC-SHA256...">
</div>
于是他便尝试使用另一个测试账号B,完成头像上传功能,对应的头像文件的s3文件名,假设为:93a1df2...png
,
然后使用前面的测试账号A,再次调用上面第3步中的确认操作API:POST /api/save-avatar
,但这次将参数fname
的值改为账号B头像的s3文件名93a1df2...png
。
然后刷新账号A的profile页面,发现头像变成了账号B的头像。查看profile页面的html内容,头像处的img
标签,填充的pre-signed url确实是指向了账号B的头像文件.
至此就可以确认这里存在越权。但是鸡肋的地方是,由于保存在S3的文件名是个hash值,基本无法暴破。
为了使bounty最大化,作者设法使漏洞危害扩大化。因为pre-signed URL既可指向一个S3桶的文件,也可以指向一个S3桶子目录。因此,他尝试如下:
POST /api/save-avatar HTTP/1.1
Host: target.com
...
fname=../
提交后,再次打开头像处的链接,就可以看到S3桶的../
子目录下的文件列表。这样就能知道其它用户的保存到S3桶的文件名了。
另外,作者还发现了(可能是根据官方文档),在Get Bucket操作时,可通过添加?prefix=prefix&marker=marker&max-keys=max-keys&delimiter=delimiter
URL参数查看1000个以上的文件对象(默认只能查看1000个文件对象)。
然后再之前的步骤,就可越权下载其它用户保存在S3桶的敏感文件了。
作者在视频最后总结了其它漏洞赏金猎人会忽视掉这个漏洞的可能原因:这里头像的链接是在一个html格式的http响应中的。如果它是通过一个rest api响应返回的,可能别人会更早发现并报告这个漏洞。
启发
(1) 在bug bounty中,测试要保持耐心、细心,不要只盯着RCE、SSRF等技术型漏洞,千万别小看、忽视任何的逻辑类、越权类漏洞。
(2) 研究云安全的时候,不要死扣云厂商自己产品的漏洞,学习重心要调整下,要对这些常用的服务(比如S3等)的使用,比如特性、配置等要熟悉,重点关注会导致安全风险的特性、配置。这些细节在漏洞利用的时候可能会发挥意想不到的作用。
(3) 由于AWS云占有量巨大,尽管Amazon没有为AWS单独开设bug bounty,但为了广大使用了AWS云的国外企业的bug bounty项目,很有必要学习。