教程和靶场来源于 Burpsuite 的官网 Portswigger:File upload vulnerabilities - PortSwigger
原理与危害
很多网站都有文件上传的功能,比如在个人信息页面允许用户上传图片作为头像。如果网站应用程序对用户上传的文件没有针对文件名、文件类型、文件内容或文件大小做充分的验证,就可能导致允许攻击者上传有潜在危险的文件,比如服务端的脚本文件,然后访问该文件以触发代码执行。
文件上传漏洞的危害取决于两个因素:
- 网站应用程序对文件名、文件类型、文件内容或文件大小等参数中的哪一个没有做充分的验证。
- 上传文件成功后受到哪些限制。
最坏的情况是文件类型没有受到服务器的任何限制,允许 .php 或 .jsp 作为脚本文件执行,那么攻击者可以上传 .php 或 .jsp 文件作为 webshell,接管服务器。
其他的一些危害:
- 对文件名没有做验证,攻击者上传一个同名的文件,覆盖服务器上已存在的文件,如果还存在路径遍历漏洞,那么危害更大,可以覆盖服务器的系统文件。
- 对文件大小没有做验证,攻击者上传一个非常大的文件,占用服务器的磁盘空间,也就是 DoS 攻击。
由于文件上传漏洞的危害很大,所以现在大部分网站应用程序都做了防御,能直接上传 .php 或 .jsp 文件的网站很少看到了。然而,漏洞仍然会产生,这是因为开发人员坚信他们的防御足够有效。
静态文件处理
在刚学习 Web 安全时,看了很多课程和书籍,我们潜意识认为一个 URL 对应网站服务器上的一个文件,对应关系是 1:1,比如 http://example.com/includes/func.php 这个 URL 在网站服务器上对应的文件位于网站根目录下的 includes 目录下的 func.php 文件。这种理解在以前静态网站甚至 PHP 网站和 ASP 网站流行的时候确实是这样,这只不过是 Apache 或 IIS 等中间件正好这样管理站点的文件,但是现代 Web 应用程序已经不是这样 URL 与文件呈现一对一的映射关系,我们现在看到一个 URL 比如 https://youkuaiyun.com/mp_blog/creation/editor,在网站服务器并不存在一个路径为 <网站根目录>/mp_blog/creation/editor 的文件。
当然,像图片、CSS 和 JS 等静态资源,Web 服务器仍然用一对一的映射关系处理它们,处理步骤是:解析 URL 中的 path 部分,识别出请求的文件的扩展名,然后根据扩展名匹配对应的 MIME,最后根据服务器预先的配置执行下一步:
- 如果文件类型是不可执行的,就作为静态文件把文件内容响应给客户端。
- 如果文件类型是可执行的,例如 PHP 文件,就创建运行环境,根据请求头和请求参数分配变量,然后执行脚本。
- 如果文件类型是可执行的,但服务器被配置成不执行该类型的文件,就给客户端响应一个错误。不过,大多数情况下,服务器仍然把这些当成普通文本,将它们的内容返回给客户端,这一点特性可能被利用实现泄露代码或其他敏感信息的目的。
实验
实验说明:
服务器没有对上传的文件没做任何验证,上传一个 PHP 脚本并读取 /home/carlos/secret 文件的内容就能完成实验。
进入实验场景: