文件上传漏洞是指:用户通过「文件上传功能」,上传「可执行脚本」文件到服务器本地,拿到服务器「权限」。
漏洞形成的核心在于:网站对上传的文件过滤不够严谨。
因此,我们学习的重点要放在:文件过滤的方式,以及如何绕过这些过滤!
1、前端绕过
1)程序员在「前端」使用「JS代码过滤」上传的文件,过滤成功以后,再向后端发送请求,代码逻辑示例:
//JS检查文件类型(大概逻辑)
function checkFile() {
//定义允许上传的文件类型
var allow_ext = ".jpg|.png|.gif";
//文件类型不满足时,返回false,并弹窗
if(){
alert(errMsg);
return false;
}
}
2)我们可以根据页面是否「向后台发送请求」,来判断前端是否有过滤。
当页面发送请求时,浏览器左下角的状态栏会「显示请求链接」(显示状态栏功能,默认开启),上传文件失败时,如果左下角不显示链接,就说明前端有过滤;如果左下角显示链接,就说明前端没有过滤(或者前端过滤已经被绕过)。
3)绕过前端过滤的方式有两种:
- 「浏览器禁用JS」(JS代码不起作用,但也会导致其他正常的JS功能也不能用)
- 「抓包」修改文件后缀(比如上传一个jpg文件,抓包修改成php文件)
对应的练习靶场: Upload LABS Pass-1
练习靶场下载:https://github.com/c0ny1/upload-labs
靶场搭建可参考 PhpStudy下载安装使用教程
2、MIME类型绕过
浏览器通过「MIME类型」(而不是文件扩展名)来标识文件的类型,也就是http请求头中的 Content-Type 字段,内容为 image/jpeg
、image/png
、image/gif
时,表示文件是图片类型。
1)程序员通过请求的MIME类型,判断是否为图片类型,代码逻辑示例:
//MIME类型过滤(大概逻辑)
if($_FILES['upload_file']['type'] == 'image/jpeg'){
//上传文件到upload路径
} else {
//提示文件类型不正确
}
2)我们可以抓包修改 Content-Type 字段的值为 image/jpeg
、image/png
、image/gif
,进行绕过。
对应的练习靶场: Upload LABS Pass-2
3、后缀名绕过
1)程序员通过「后缀名黑名单」,禁止上传指定类型的文件,代码逻辑示例:
# 获取上传的文件名
$file_name = trim($_FILES['upload_file']['name']);
# 定义黑名单
$deny_ext = array('.asp','.aspx','.php','.jsp');
# 判断上传的文件
if(!in_array($file_ext, $file_name)) {
# 如果不在黑名单中,就上传文件。
} else {
# 如果在黑名单中,就弹窗提示,禁止上传。
$msg = '不允许上传.asp,.aspx,.php,.jsp后缀文件!';
}
2)我们可以把文件后缀名改成黑名单之外的格式,绕过过滤。
绕过黑名单上传成功后,需要能够「解析」这类文件才能使用,是否能够解析取决于Apache配置文件中有没有添加这些后缀名。
比如:你想让Apache能够解析 .phtml
、.php5
、.phps
、.pht
,就在Apache的httpd.conf需配置 AddType application/x-httpd-php .php .phtml .php5
常见的可执行脚本后缀名如下:
.php
、.php1
、.php2
、.php3
、.php4
、.php5
、.pht
、.phps
、.phtml
.asp
、.aspx
、.asa
、.asax
、.ascx
、.ashx
、.asmx
.jsp
、.jspa
、.jspx
、.jsw
、.jsv
、.jspf
、.jtml
.html
、.htm
.cer
、.swf
、.ini
对应的练习靶场:
Upload LABS Pass-5
Upload LABS Pass-6
Upload LABS Pass-8
Upload LABS Pass-9
Upload LABS Pass-10
Upload LABS Pass-11
4、.htaccess绕过
.htaccess
是Apache的分布式配置文件,可以让当前目录下的文件当做php文件执行。
使用前提:
- Apache的http.conf配置
AllowOverride ALL
以及AccessFileName .htaccess
- 未过滤
.htaccess
文件,且上传后不修改文件名,也就是说,文件名必须是.htaccess才会生效。
1)我们先上传一个 .htaccess
,内容为:
<FilesMatch "shell.jpg">
SetHandler application/x-httpd-php
</FilesMatch>
代码的意思是,让当前目录下的shell.jpg
当做php文件执行。
再上传一个 shell.jpg
,内容为一句话木马 <?php eval($_GET['shell']);?>
,访问shell.jpg
文件即可。
对应的练习靶场: Upload LABS Pass-4
5、点绕过
Windows系统为了保证文件命名的规范性,会把文件名末尾的点删掉。
我们在上传文件时抓包,在文件名默认加上点,比如 xx.php.
;
后端过滤时会把 php.
当做文件后缀名,从而绕过很多过滤;
文件上传成功落地时,系统的命名机制删掉末尾的点,变成 xx.php
,文件就能正常执行了。
6、防御
文件上传漏洞的防护有三个方向,分别是文件名、文件内容和权限
- 「文件名」包括过滤「文件后缀名」,修改上传后的文件名(比如基于时间的随机字符串),同时禁止「文件路径」对外展示。
- 「文件内容」主要是针对图片马,对文件进行「二次渲染」,这是最变态的一种方式,可以避免大部分文件上传漏洞。
- 其次是「权限」,「文件上传目录」取消执行权限,使上传的脚本不能执行。