什么是文件上传漏洞?
文件上传漏洞是指 Web 服务器允许用户将文件上传到其文件系统,而无需充分验证其名称、类型、内容或大小等内容。如果不能正确执行这些限制,就意味着即使是基本的图像上传功能也可以用来上传任意和潜在危险的文件。这甚至可能包括支持远程代码执行的服务器端脚本文件。
在某些情况下,上传文件的行为本身就足以造成损害。其他攻击可能涉及对文件的后续 HTTP 请求,通常用于触发服务器执行该文件。
文件上传漏洞是如何产生的?
鉴于相当明显的危险,一些网站很少对允许用户上传的文件没有任何限制。更常见的是,开发人员实现了他们认为是健壮的验证,这些验证要么存在固有缺陷,要么很容易被绕过。
如:他们可能尝试将危险文件类型列入黑名单,但在检查文件扩展名时无法考虑解析差异。与任何黑名单一样,也很容易意外地遗漏可能仍然危险的更晦涩的文件类型。
在其他情况下,网站可能会尝试通过验证攻击者可以使用 Burp Proxy 或 Repeater 等工具轻松操纵的属性来检查文件类型。
最终,即使是强大的验证措施也可能在构成网站的主机和目录网络中不一致地应用,从而导致可利用的差异。
利用不受限制的文件上传来部署 Web Shell
从安全角度来看,最糟糕的情况是网站允许上传服务器端脚本,例如 PHP、Java 或 Python 文件,并且还配置为将它们作为代码执行。这使得在服务器上创建自己的 Web shell 变得微不足道。
Web 外壳
Web Shell 是一种恶意脚本,攻击者只需向正确的端点发送 HTTP 请求,即可在远程 Web 服务器上执行任意命令。
如果能够成功上传 Web Shell,则实际上可以完全控制服务器。这意味着可以读取和写入任意文件,泄露敏感数据,甚至使用服务器对内部基础设施和网络外部的其他服务器进行攻击。
如:以下 PHP 单行代码可用于从服务器的文件系统中读取任意文件:
<?php echo file_get_contents('/path/to/target/file'); ?>
上传后,发送对此恶意文件的请求将在响应中返回目标文件的内容。
通用的 Web shell
<?php echo system($_GET['command']); ?>
通过查询参数传递任意系统命令,如下所示:
GET /example/exploit.php?command=id HTTP/1.1
有缺陷的文件类型验证
提交HTML表单时,浏览器通常会在请求中发送提供的数据,其内容类型为。这适用于发送简单的文本
-
例如姓名或地址。但是,它不适合发送大量二进制数据,
-
例如整个图像文件或 PDF 文档。在这种情况下,首选内容类型
POST``application/x-www-form-url-encoded
,multipart/form-data
-
对于表单的每个输入,消息正文被拆分为单独的部分。每个部分都包含一个标题,该标题提供有关其相关输入字段的一些基本信息。这些单独的部分还可能包含它们自己的标头,该标头告诉服务器使用此输入提交的数据的 MIME 类型。
Content-Disposition
,Content-Type
网站可能尝试验证文件上传的一种方法是检查此特定于输入的标头是否与预期的 MIME 类型匹配。
- 例如,如果服务器只需要图像文件,则它可能只允许像 和 这样的类型。当服务器隐式信任此标头的值时,可能会出现问题。
- 如果没有执行进一步的验证来检查文件的内容是否真的与假定的 MIME 类型匹配,则可以使用 Burp Repeater 等工具轻松绕过此防御。
Content-Type
,image/jpeg
,image/png
练习
这里以bp的实验室为例
通过 Web Shell 上传远程执行代码
目标
/home/carlos/secret
访问实验室
登录
- 登录题目中给到的用户
抓包
- 发现文件上传
- 测试上传
- 准备一张图片
- 利用bp抓包查看
- 进行流量分析
上传一张.jpg
文件
上传成功
- 查看抓包
筛选图片
查看数据包
- 这里发现路径
/files/avatars/qwe.jpg
上传一句话木马
-
利用传参方式上传php一句话
-
这里利用图片的数据包进行改包进行放包
-
这里利用一个
POST
,和一个GET
包
改包
-
对
POST
传参的内容进行更改 -
修改
GET
数据包 -
首先更改
POST
数据包 -
这里需要更改
filename
的文件名称,和要传递的内容
测试上传
<?php echo file_get_contents('/ect/passwd'); ?>
<?php echo file_get_contents('/home/carlos/secret'); ?>
测试成功
- 这里成功查看到了
passwd
文件
获取secret文件内容
-
继续利用图片的数据包进行改参
-
进行上马
-
利用
post
传参,改参 -
放包更改
GET
数据包
上传成功
成功拿到,secret
文件内容
提交
al3rtVQaOYvblsgLgfVKgZ4VnUx3Gdyk