【THM-课程内容答案】:Web Hacking Fundamentals-Upload Vulnerabilities-Filtering
迄今为止,我们几乎完全忽视了网页开发者用于防御文件上传漏洞的反制措施。在THM里,你成功攻击过的每一个网站都毫无安全性可言。是时候做出改变了。接下来,我们将探讨一些用于阻止恶意文件上传的防御机制,以及如何绕过这些机制。
首先,我们来探讨客户端过滤与服务器端过滤的区别。
当我们讨论脚本是“客户端”的时候,在Web应用的语境下,指的是该脚本运行在用户浏览器中而非Web服务器本身。JavaScript几乎是客户端脚本语言的通用选择,尽管也存在其他替代方案。无论使用何种语言,客户端脚本都会在你的浏览器中运行。在文件上传的场景中,这意味着过滤动作会在文件上传至服务器之前完成。理论上这看似合理,对吧?在理想情况下确实如此;但如果过滤这个动作发生在本地计算机上,那就极易绕过。因此,仅靠客户端过滤本身是一种极不安全的验证方法,无法确保上传文件不包含恶意内容。
相反,正如您可能猜到的那样,服务器端脚本将在服务器上运行。传统上,PHP是主要的服务器端语言(微软的IIS ASP紧随其后);然而,近年来,其他选项(C#、Node.js、Python、Ruby on Rails等)的使用越来越广泛。服务器端的过滤往往更难绕过,因为你面前没有代码,代码是在服务器上执行的,所以在大多数情况下,也不可能完全绕过过滤器。因此我们必须形成一个适用现有过滤器的有效载荷,让它仍然允许我们执行代码。
考虑到这一点,让我们来看看一些不同类型的过滤。
扩展验证:
文件扩展名用于标识文件的内容。在实践中,它们很容易改变,所以实际上意义不大;然而,MS Windows仍然使用它们来识别文件类型,尽管基于Unix的系统往往依赖于其他方法,我们将在稍后介绍。检查扩展名的过滤器有两种工作方式:他们要么将扩展名列入黑名单(即列出不允许的扩展名),要么将扩展列为白名单(即列明允许的扩展,并拒绝其他所有扩展名)。
文件类型筛选:
与扩展验证类似,但更密集的是,文件类型过滤再次验证文件的内容是否可以上传。我们将研究两种类型的文件类型验证:
- MIME验证:MIME(Multipurpose Internet Mail Extension 多用途互联网邮件扩展)类型被用作文件的标识符——最初是在用在电子邮件作的附件传输时进行标识,但现在也是在通过HTTP(S)传输文件时进行标识。文件上传的MIME类型附加在请求的头部,看起来像这样:
MIME类型遵循<type>/<subtype>格式。在上面的请求中,您可以看到图像“spaniel.jpg”已上传到服务器。作为合法的JPEG图像,此上传的MIME类型为“image/JPEG”。可以在客户端和/或服务器端检查文件的MIME类型;然而,由于MIME基于文件的扩展名,因此很容易绕过。
- 幻数验证:幻数是确定文件内容的更准确的方法;尽管如此,它们绝不是不可能伪造的。文件的“幻数”是文件内容开头的一串字节,用于标识内容。例如,PNG文件的最顶部将有这些字节:89 50 4E 47 0D 0A 1A 0A。
与Windows不同,Unix系统使用幻数来标识文件;然而,在处理文件上传时,可以检查上传文件的幻数,以确保可以安全地接受。这绝不是一个有保证的解决方案,但它比检查文件的扩展名更有效。
文件长度筛选:
文件长度过滤器用于防止大型文件通过上传表单上传到服务器(因为这可能会使服务器资源不足)。在大多数情况下,当我们上传shell时,这不会给我们带来任何问题;然而,值得注意的是,如果上传表单只期望上传一个非常小的文件,那么可能会有一个长度过滤器来确保遵守文件长度要求。例如,我们在上一个任务中成熟的PHP反向shell是5.4Kb大,相对较小,但如果表单期望的最大值为2Kb,那么我们需要找到一个替代shell来上传。
文件名筛选:
如前所述,上传到服务器的文件应该是唯一的。通常这意味着在文件名中添加一个随机方面,但是,另一种策略是检查服务器上是否存在同名文件,如果存在,则向用户发出错误。此外,文件名应在上传时进行消毒,以确保它们不包含任何“可疑字符”,这可能会在上传时对文件系统造成问题(例如Linux上的空字节或正斜杠,以及控制字符,如;和可能的unicode字符)。这对我们来说意味着,在管理良好的系统上,我们上传的文件不太可能与上传前的已存的文件的名称相同,所以请注意,如果你设法绕过内容过滤,你可能不得不寻找你的shell。
文件内容筛选:
更复杂的过滤系统可能会扫描上传文件的全部内容,以确保它不会欺骗其扩展名、MIME类型和幻数。这是一个比大多数基本过滤系统所采用的过程复杂得多的过程,因此本节课将不涉及。
值得注意的是,这些过滤器本身都不是完美的——它们通常会相互结合使用,提供多层过滤器,从而显著提高上传的安全性。这些过滤器中的任何一个都可以应用于客户端、服务器端或两者。
同样,不同的框架和语言都有自己固有的过滤和验证上传文件的方法。因此,可能会出现特定语言的漏洞;例如,在PHP主版本5之前,可以通过向恶意.PHP文件附加一个空字节,后跟一个有效的扩展名来绕过扩展名过滤器。最近,还可以将PHP代码注入到其他有效图像文件的exif数据中,然后强制服务器执行它。如果您感兴趣,欢迎您进一步研究这些内容。
【题目&答案】:
传统上占主导地位的服务器端脚本语言是什么? What is the traditionally predominant server-side scripting language?
PHP
当按文件扩展名进行验证时,您会称之为可接受的扩展名列表(服务器拒绝列表中没有的任何扩展名)吗? When validating by file extension, what would you call a list of accepted extensions (whereby the server rejects any extension not in the list)?
Whitelist
[研究]上传CSV文件时,您希望看到什么MIME类型? [Research] What MIME type would you expect to see when uploading a CSV file?
text/csv
