文件上传的总结

   一.定义:

           文件上传漏洞是用户上传了一个可执行脚本,然后通过该文件获得访问服务器的权限的漏洞。


   二.原理:

             大部分的网站都有文件上传的功能,比如上传png,php,exe等文件,一些能被网站给过滤,但大部分的web过滤不够严格,导致在上传位置上,可以上传一些带脚本的文件,web端对php进行解析,可以执行任意脚本的文件。


        三.文件上传的校验流程

     


   

 四.文件上传漏洞的成功前提:

1.网站有文件上传的功能

2.文件类型能够上传
3.知道上传的路径
4.上传的文件可以执行或被包含

   


五.文件上传漏洞的类型:

          (1)js检查(客户端校验)

          随便上传一个文件,它是否会有提示,什么类型可以上传。一般禁用java script或删除代码。

           (2)后端黑名单绕过

                          扩展名绕过(客户端校验)

                一般上传一个后缀名为 .txt的木马, 利用burpsuite改后缀名为 .php  / .jsp  /.asp     

                           后缀 大小写绕过

                后缀显示非法时,可将  .php 改为 .Php 或 .PhP

                             后缀双写绕过

             web代码中会将可能存在漏洞的脚本文件后缀名进行过滤,大部分情况下只能过滤一层,可改为   .pphphp

                               空格绕过

                正常的php脚本不可以绕过,但是后面加上一个空格即可绕过,比如  .php改为  . php

                                 点绕过

                  在后面加一个点,比如  .php改为  .php.

                                

                           .htaccess解析

      .htaccess文件(或者"分布式配置文件"),全称是Hypertext Access(超文本入口)。提供了针对目录改变配置的方法,即,在一个特定的文档目录中放置一个包含一个或多个指令的文件,以作用于此目录及其所有子目录。作为用户,所能使用的命令受到限制。管理员可以ApacheAllowOverride指令来设置。

方法:直接上传这个文件,看是否可以获得权限,改后缀为 .htaccess

                                

                        ::$DATA绕过

在window的时候如果文件名+"::D A T A " 会 把 : : DATA"会把::DATA"会把::DATA之后的数据当成文件流处理,不会检测后缀名,且保持::$DATA之前的文件名,他的目的就是不检查后缀名.利用burpsuite抓包,改包,将  .php改为  .php::DATA

                (3)后端白名单绕过

                              00截断绕过

0x00截断原理:

0x00是十六进制表示方法,是ascii码为0的字符,在有些函数处理时,会把这个字符当做结束符。系统在对文件名的读取时,如果遇到0x00,就会认为读取已结束。这个可以用在对文件类型名的绕过上。但要注意是文件的16进制内容里的00,而不是文件名中的00.就是说系统是按16进制读取文件(或者说二进制),遇到ascii码为零的位置就停止,而这个ascii码为零的位置在16进制中是00,用0x开头表示16进制,也就是所说的0x00截断。%00是被服务器解码为0x00发挥了截断作用。

    通过post传进来,用Burp抓包,在二进制中找到文件名,在文件名后的位置的二进制数值进行修改为00,因为post不会像get对%00进行自动解码。

     通过get传进来的,代码中,文件路径采用字符串拼接的方式,因此可以利用%00截断绕过

用Burp抓包,在数据包第一行的url请求文件名后加上%00,

                                mime文件绕过

客户端软件,区分不同种类的数据,例如web浏览器就是通过MIME类型来判断文件是GIF图片,还是可打印的PostScript文件。web服务器使用MIME来说明发送数据的种类,web客户端使用MIME来说明希望接收到的数据种类。利用burpsuite抓包改包。

            (4)其他绕过

                            条件竞争

网站允许上传文件,然后检查上传文件是否包含webshell、是否是指定的文件类型。如果不是,那么删除该文件。在删除之前访问上传的php文件,从而执行上传文件中的php代码。绕过方法: 先进行文件上传,后进行判断与删除。利用时间差进行webshell上传。

                               二次渲染

         上传两次,通过上传同一个文件,进行对比,在相同点添加脚本代码。

              (5)绕过WAF

   详解在:干货 | 最全的文件上传漏洞之WAF拦截绕过总结-腾讯云开发者社区-腾讯云

    以上皆是个人看法,如有不对请多指正。谢谢!!!

六.例题:

来自buuctf n1book

先来看一下源代码,基本知道考点为  zip路径穿越 和 1.php.xxx

  1.   <?php
    header("Content-Type:text/html; charset=utf-8");
    // 每5分钟会清除一次目录下上传的文件
    
    //会包含文件pclzip.lib.php,感觉这个php里面是有一些针对zip包进行解压等的操作的
    require_once('pclzip.lib.php');
    
    //要是没上传文件,就输出上传页面
    if(!$_FILES){
    echo '省略的HTML'
        show_source(__FILE__);
    }else{
        $file = $_FILES['file'];
    
    //限制上传的文件名不为空
        if(!$file){
            exit("请勿上传空文件");
        }
        $name = $file['name'];
    
        $dir = 'upload/';
        $ext = strtolower(substr(strrchr($name, '.'), 1));
         $path = $dir.$name;
    //strrchr($name, '.') 
    //strrchr() 函数查找字符串在另一个字符串中最后一次出现的位置,并返回从该位置到字符串结尾的所有字符。
    //比如上传的文件名为$name=1.php.txt,这里strrchr($name, '.') 执行结果为.txt
    //substr(strrchr($name, '.'), 1)
    //substr字符串截取,从下标为1开始截取,那就是把点略过,截取后为txt
    //通过strtolower函数将所有字符转换为小写,赋值给ext变量
    //如果我们上传的文件名为1.txt,那么path变量就为upload/1.txt
    
    
    //检查是否为目录
        function check_dir($dir){
            $handle = opendir($dir);
            while(($f = readdir($handle)) !== false){
                if(!in_array($f, array('.', '..'))){
                    if(is_dir($dir.$f)){
                        check_dir($dir.$f.'/');
                     }else{
                        $ext = strtolower(substr(strrchr($f, '.'), 1));
                        if(!in_array($ext, array('jpg', 'gif', 'png'))){
                            unlink($dir.$f);
                        }
                    }
                
                }
            }
        }
        
    //创建目录    
        if(!is_dir($dir)){
            mkdir($dir);
        }
    
    
        $temp_dir = $dir.md5(time(). rand(1000,9999));
        if(!is_dir($temp_dir)){
            mkdir($temp_dir);
        }
    //这里应该就是最难的了,大概就是将目录名拼接一个随机数,读到这里,基本上就知道需要路径穿越了
    因为我们不知道随机数值,所以就算绕过上传,解析也是一大关(路径不难找,就是解析难)
    
    
    //首先进行后缀的校验,把刚刚拿到的,最后一个.后面的字符串和这里的zip、jpg、gif、png进行对比校验
        if(in_array($ext, array('zip', 'jpg', 'gif', 'png'))){
            if($ext == 'zip'){
    //使用PclZip进行解压缩        
                $archive = new PclZip($file['tmp_name']);
    //遍历解压缩后的每个目录            
                foreach($archive->listContent() as $value){
                    $filename = $value["filename"];
    //一段较为简单的正则,就是匹配每个文件结尾的位置,是否是.php                
                    if(preg_match('/\.php$/', $filename)){
                         exit("压缩包内不允许含有php文件!");
                     }
                }
                if ($archive->extract(PCLZIP_OPT_PATH, $temp_dir, PCLZIP_OPT_REPLACE_NEWER) == 0) {
                    check_dir($dir);
                       exit("解压失败");
                }
    
                check_dir($dir);
                exit('上传成功!');
            }else{
                move_uploaded_file($file['tmp_name'], $temp_dir.'/'.$file['name']);
                check_dir($dir);
                exit('上传成功!');
            }
        }else{
            exit('仅允许上传zip、jpg、gif、png文件!');
        }
    }
    
    

pclzip()

    产生zip压缩档;列出压缩档内容 listContent( ) :列出压缩档中的内容,包括档案的属性与目录;extract([options list]) :解压缩PKZIP中的档案或目录。

strrchr()

    查找字符串在另一个字符串中最后一次出现的位置,并返回从该位置到字符串结尾的所有字符。比如上传的文件名为$name=1.php.txt,这里strrchr($name, '.') 执行结果为.txt。
substr(strrchr($name, '.'), 1)substr字符串截取,从下标为1开始截取,那就是把点略过,截取后为txt通过strtolower函数将所有字符转换为小写,赋值给ext变量,如果我们上传的文件名为1.txt,那么path变量就为upload/1.txt

绕过路径检测

    通过路径穿越来到web的根目录下,返回两级目录,一级是upload,另一级是随机值(根据源代码的)使用 ../../

apache换行解析漏洞

    影响范围:2.4.0-2.4.29版本
原因:合法后缀配置文件中的正则表达式中$不仅匹配字符串结尾位置,还可以匹配\n或\r,在解析php时,1.php\x0A将按照.php进行解析,而’.php\x0A’ != ‘.php’,可能过滤时过滤了.php但没有过滤.php\x0A从而实现绕过。配置文件:过滤后缀名.phpapache 2.4.7 无法上传hhh.php,上传hhh.php.xxx可以绕过。

新建一个文件,文件名长度要为18,因为构造的的为/../../hhh.php.xxx

压缩为zip

          利用010 打开并修改文件名

          

             

             之后直接上传即可得到flag

           

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值