文件上传限制绕过的原理以及方法总结
0x00 概述
文件上传漏洞是指用户上传了一个可执行的脚本文件,并通过此脚本文件获得了执行服务器端命令的能力。文件上传这个功能本身没有问题,有问题的是文件上传后,服务器怎么处理、解释文件。如果服务器的处理逻辑不够安全,就会导致上传的文件被web容器解释执行,从而造成严重的后果
0x01 客户端js检测检测绕过
检测原理
在客户端通过如下的javascript代码来检测用户提交的文件是否合法:
<script type="text/javascript">
function checkFile() {
var file = document.getElementsByName('upload_file')[0].value;
if (file == null || file == "") {
alert("请选择要上传的文件!");
return false;
}
//定义允许上传的文件类型
var allow_ext = ".jpg|.png|.gif";
//提取上传文件的类型
var ext_name = file.substring(file.lastIndexOf("."));
//判断上传文件类型是否允许上传
if (allow_ext.indexOf(ext_name) == -1) {
var errMsg = "该文件不允许上传,请上传" + allow_ext + "类型的文件,当前文件类型为:" + ext_name;
alert(errMsg);
return false;
}
}
</script>
如何判断是否是客户端js检测
1、选择一个.php后缀的文件,同时使用burpsuite进行抓包
2、点击上传,可以看到还没有数据经过burpsuite,浏览器就已经弹出警示框,说明数据还没有发送给服务器,程序就判断出来文件类型不对,因此就可以得出结论这个是通过客户端进行的本地文件检测
绕过方法
由于用来验证文件合法性的js程序在我们客户端,所以对于我们来说,这个验证程序是可控制的,能够很轻易的就绕过,具体能够绕过的方法如下:
1. 添加允许上传的文件类型,使自己想要上传的会见类型为合法
-这是一个简单的上传页面
-在上传按钮处单击右键,选择审查元素选项
-打开浏览器控制台,浏览html源码,找到用来验证的js脚本
-修改js脚本,将自定义的文件类型后缀添加进去
-成功上传:
2、删除对js验证脚本的调用,使其不能对上传的文件类型做检测,从而达到绕过
-同样的通过审查元素,查看到form表单的内容,form的开始标签为<form enctype="multipart/form-data" method="post" onsubmit="return checkFile()">,
其中的onsubmit="return checkFile()的作用就是当点击上传按钮的时候,就会触发js验证脚本,所以将这一部分删除,变可以成功绕过检测
3、利用burpsuite抓包,修改文件类型进行绕过
-首先将我们想要上传的恶意脚本的后缀更改为符合要求的文件类型后缀
如:webshell.php -> webshell.jpg
-当点击上传的时候使用burp进行抓包,将名字的后缀改回.php,以便上传至服务器能够正确解析
-成功上传
0x02 服务器端MIME类型检测绕过
检测原理
当用户上传文件到服务器端的时候,服务器端的程序会获取上传文件的MIME类型,然后用这个获取到的类型来和期望的MIME类型进行匹配,如果匹配不上则说明上传的文件不合法。服务端检测MIME类型的代码如下:
if(($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif')){
...//判断过后对文件处理的进一步操作}
绕过方法
因为服务端检测的是文件的MIME类型,而对这个MIME类型的的值的获取是通过HTTP请求字段里的Content-Type字段
,所以绕过的方法就是通过修改Content-Type的值,比如修改为image/jpeg;image/png;image/gif等等允许上传类型对应的MIME值
0x03 黑名单绕过
检测原理
文件类型根据黑名单来检测的原理就是:服务器程序根据一份文件后缀名的名单来判断是否允许当前文件上传到服务器,只要上传的文件的类型能够和这个黑名单里面的类型匹配,那么就禁止该文件上传
绕过方法
1. 文件名大小写绕过
用像AsP,pHp之类的文件名绕过黑名单检测
2. 名单列表绕过
用黑名单里没有的名单进行攻击,比如黑名单里没有asa或cer之类
3. 特殊文件名绕过
比如发送的http包里把文件名改成test.asp.或test.asp_(下划线为空格),这种命名方式
在windows系统里是不被允许的,所以需要在burp之类里进行修改,然后绕过验证后,会
被windows系统自动去掉后面的点和空格,但要注意Unix/Linux系统没有这个特性。
4.0x00截断绕
过
5. .htaccess文件攻击
6. 解析调用/漏洞绕过
0x04 白名单绕过
...
0x05 服务端文件类容检测绕过
检测原理
0x06 web应用程序解析绕过
1. Apache解析漏洞
解析:test.php.(任意不属于黑名单且也不属于Apache解析白名单的名称),比如test.php.lala
描述:一个文件名为test.x1.x2.x3的文件,apache会从x3的位置开始尝试解析,如果x3不属于apache能够解析的扩展名,那么apache会尝试去解析x2,直到能够解析到能够解析的为止,否则就会报错
2. IIS解析漏洞
解析 :test.asp/(任意文件名)|test.asp;(任意文件名) | (任意文件名)/(任意文件名).php
描述:IIS6.0在解析asp格式的时候有两个解析漏洞,一个是如果目录名包含".asp"字符串,
那么这个目录下所有的文件都会按照asp去解析,另一个是只要文件名中含有".asp;"
会优先按asp来解析
IIS7.0/7.5是对php解析时有一个类似于Nginx的解析漏洞,对任意文件名只要在URL
后面追加上字符串"/任意文件名.php"就会按照php的方式去解析;
3. Nginx解析漏洞
解析: (任意文件名)/(任意文件名).php | (任意文件名)%00.php
描述:目前Nginx主要有这两种漏洞,一个是对任意文件名,在后面添加/任意文件名.php
的解析漏洞,比如原本文件名是test.jpg,可以添加为test.jpg/x.php进行解析攻击。
还有一种是对低版本的Nginx可以在任意文件名后面添加%00.php进行解析攻击。