文件上传绕过学习

 

漏洞成因:

在文件上传的功能处,若服务端脚本语言未对上传的文件进行严格验证和过滤,导致恶意用户上传恶意的脚本文件时,就有可能获取执行服务端命令的能力。

常见的绕过方式:

前端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截断绕过:

绕过方式

00截断

 

二次渲染绕过:

绕过方式:

二次渲染

 

条件竞争绕过:

绕过方式:通过BURP不断发包,导致不断写入Webshell,再写入速度频率上超过安全软件查杀频率,导致绕过。

 

垃圾数据填充绕过:

绕过方式:修改HTTP请求,再之中加入大量垃圾数据。

垃圾字符文件上传绕过waf

 

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请求,再之加入大量垃圾数据。

 

 

 

posted @ 2021-03-25 13:10  夜布多  阅读(401)  评论(0编辑  收藏  举报