zoukankan      html  css  js  c++  java
  • 文件上传 uploadlabs

    BUUCTF=>Basci=>Upload-Labs-Linux 1

    思维导图

    客户端 检查

    Pass-1 js检查

    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;
        }
    }
    

    1.浏览器(FireFox)禁用js

    about:config
    

    2.F12删除掉检查函数

    服务端 黑名单

    Pass-2 MIME-Type类型

    $is_upload = false;
    $msg = null;
    if (isset($_POST['submit'])) {
        if (file_exists(UPLOAD_PATH)) {
            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 . '/' . $_FILES['upload_file']['name']            
                if (move_uploaded_file($temp_file, $img_path)) {
                    $is_upload = true;
                } else {
                    $msg = '上传出错!';
                }
            } else {
                $msg = '文件类型不正确,请重新上传!';
            }
        } else {
            $msg = UPLOAD_PATH.'文件夹不存在,请手工创建!';
        }
    }
    
    

    这关只对Content-Type:进行了验证

    if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_file']['type'] == 'image/gif')) {
               ......
            } else {
                $msg = '文件类型不正确,请重新上传!';
            }
    

    1.修改Content-Type

    MIME (Multipurpose Internet Mail Extensions) 是描述消息内容类型的因特网标准。
    MIME 消息能包含文本、图像、音频、视频以及其他应用程序专用的数据。


    2.Burp改包shell.png =>shell.php

    Pass-3 可解析特殊后缀

    $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 . '文件夹不存在,请手工创建!';
        }
    }
    
    

    上传特殊后缀文件,能被php解析,但文件名被改了

    1.Proxy->Repater->raw记着改过后的文件名
    2.直接就拖图片到搜索框(图片的href就是它保存的位置)

    Pass-4 分布式配置文件 .htaccess

    $is_upload = false;
    $msg = null;
    if (isset($_POST['submit'])) {
        if (file_exists(UPLOAD_PATH)) {
            $deny_ext = array(".php",".php5",".php4",".php3",".php2","php1",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2","pHp1",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf");
            $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.'/'.$file_name;
                if (move_uploaded_file($temp_file, $img_path)) {
                    $is_upload = true;
                } else {
                    $msg = '上传出错!';
                }
            } else {
                $msg = '此文件不允许上传!';
            }
        } else {
            $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
        }
    }
    
    $deny_ext = array(".php",".php5",".php4",".php3",".php2","php1",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2","pHp1",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf");
    

    虽然没有过滤pphhpp但它解析出来是文本形式,怎么把它解析成php呢

    .htaccess文件(或者"分布式配置文件"),全称是Hypertext Access(超文本入口)。
    概述来说,htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过htaccess文件,可以帮我们实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。
    Unix、Linux系统或者是任何版本的Apache Web服务器都是支持.htaccess的,但是有的主机服务商可能不允许你自定义自己的.htaccess文件。
    启用.htaccess,需要修改httpd.conf,启用AllowOverride,并可以用AllowOverride限制特定命令的使用。如果需要使用.htaccess以外的其他文件名,可以用AccessFileName指令来改变。例如,需要使用.config ,则可以在服务器配置文件中按以下方法配置:AccessFileName .config 。
    笼统地说,.htaccess可以帮我们实现包括:文件夹密码保护、用户自动重定向、自定义错误页面、改变你的文件扩展名、封禁特定IP地址的用户、只允许特定IP地址的用户、禁止目录列表,以及使用其他文件作为index文件等一些功能。

    .htaccess

    <FilesMatch "任意后缀木马文件名"
    SetHandler application/x-httpd-php
    </FilesMatch>
    

    上传shell.hugboy马,蚁剑连接

    Pass-5 大小写绕过

    $is_upload = false;
    $msg = null;
    if (isset($_POST['submit'])) {
        if (file_exists(UPLOAD_PATH)) {
            $deny_ext = array(".php",".php5",".php4",".php3",".php2",".html",".htm",".phtml",".pht",".pHp",".pHp5",".pHp4",".pHp3",".pHp2",".Html",".Htm",".pHtml",".jsp",".jspa",".jspx",".jsw",".jsv",".jspf",".jtml",".jSp",".jSpx",".jSpa",".jSw",".jSv",".jSpf",".jHtml",".asp",".aspx",".asa",".asax",".ascx",".ashx",".asmx",".cer",".aSp",".aSpx",".aSa",".aSax",".aScx",".aShx",".aSmx",".cEr",".sWf",".swf",".htaccess");
            $file_name = trim($_FILES['upload_file']['name']);
            $file_name = deldot($file_name);//删除文件名末尾的点
            $file_ext = strrchr($file_name, '.');
            $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 = '此文件类型不允许上传!';
            }
        } else {
            $msg = UPLOAD_PATH . '文件夹不存在,请手工创建!';
        }
    }
    
    

    这关删去了此行代码

    $file_ext = strtolower($file_ext); //转换为小写
    

    Pass-6 空格绕过 (windows)

    if (!in_array($file_ext, $deny_ext)) {
                ......
            } else {
                $msg = '此文件不允许上传';
            }
    

    代码比较时会带上空格去和黑名单匹配,burp改包文件名shell.php windows会自动忽略后面的空格
    识别为shell.php

    Pass-7 点号绕过

    这关删去了此行代码

    $file_name = deldot($file_name);//删除文件名末尾的点
    

    Burp改包shell.php=>shell.php.

    Pass-8 ::$DATA绕过 (windows)

    这关删去了此行代码

    $file_ext = str_ireplace('::$DATA', '', $file_ext);//去除字符串::$DATA
    

    在window的时候如果文件名+"::$DATA"会把::$DATA之后的数据当成文件流处理,不会检测后缀名,
    且保持::$DATA之前的文件名,他的目的就是不检查后缀名
    例如:"phpinfo.php::$DATA"Windows会自动去掉末尾的::$DATA变成"phpinfo.php"

    Burp改包shell.php=>shell.php::$DATA

    Pass-9 点+空格+点 (windows)

    虽然有以下检查

            $file_name = deldot($file_name);//删除文件名末尾的点
            ......
            $file_ext = trim($file_ext); //首尾去空
    

    但我们Burp改包shell.php=>shell.php. .相当于Pass-7 点号绕过

    Pass-10 双写绕过

    $file_name = str_ireplace($deny_ext,"", $file_name);
    

    上传shell.pphphp,shell.phphpp。。。

    服务端 白名单

    Pass-11 白名单 Get%00 截断(PHP<php.534)

    先上传shell.png
    Burp改包修改保存目录save_path: shell.php=>shell.php%00

    Pass-12 白名单 POST%00 截断(PHP<php.534)

    服务端 图片马

    图片马上传后,服务器不能解析,我们要结合文件包含漏洞才能利用。

    Pass-13 图片马

    这关是根据上传文件内容来判断图片类型,具体如下

    $file = fopen($filename, "rb");
        $bin = fread($file, 2); //只读2字节
        fclose($file);
        $strInfo = @unpack("C2chars", $bin);//unpack方式解码    
        $typeCode = intval($strInfo['chars1'].$strInfo['chars2']);//用intval分别把2字节内容转换为10进制后拼接
        $fileType = '';    
        switch($typeCode){      //根据计算出的$typeCode判断图片类型
            case 255216:            
                $fileType = 'jpg';
                break;
            case 13780:            
                $fileType = 'png';
                break;        
            case 7173:            
                $fileType = 'gif';
                break;
            default:            
                $fileType = 'unknown';
            }    
            return $fileType;
    }
    

    我们构造图片类型正确,但包含shell内容的图片
    pngjpg类型构造方式

    copy image.png/b + phpinfo.php = pngphpinfo.png
    

    gif类型构造方式(其实只是绕过,并未真正构造)

    Pass-14 getimagesize()绕过

    绕过方法同Pass-13,只不过换了一种验证图片类型的方式。

    function isImage($filename){
        $types = '.jpeg|.png|.gif';
        if(file_exists($filename)){
            $info = getimagesize($filename);//获取图片参数
            $ext = image_type_to_extension($info[2]);//索引2代表图片的类型
            if(stripos($types,$ext)>=0){
                return $ext;
            }else{
                return false;
            }
        }else{
            return false;
        }
    }
    

    另:
    getimagesize(string $filename [,array &$imageinfo])//获取图像信息,返回一个数组
    /*
    返回的数组中,索引0:图像宽度像素值
    索引1:图像高度像素值
    索引2:图像类型,1=GIF,2=JPG,3=PNG,4=SWF,5=PSD,6=BMP,7=TIFF_II,8=TIFF_MM,9=JPC,10=JP2,11=JPX,12=JB2,13=SWC,14=IFF,15=WBMP,16=XBM,17=ICO,18=COUNT
    索引3:图像宽度和高度的字符串
    索引bits:图像的每种颜色的位数,二进制格式
    索引channels:图像的通道值
    索引mime:图像的MIME信息
    /
    image_type_to_extension(int $imagetype [,bool $include_dot = TRUE])//获取图像类型的文件扩展名
    /

    include_dot是否在扩展名前加点。默认为TRUE
    */

    Pass-15 exif_imagetype() 绕过

    绕过方法同Pass-13,只不过换了一种验证图片类型的方式。

    function isImage($filename){
        //需要开启php_exif模块
        $image_type = exif_imagetype($filename);//
        switch ($image_type) {
            case IMAGETYPE_GIF:
                return "gif";
                break;
            case IMAGETYPE_JPEG:
                return "jpg";
                break;
            case IMAGETYPE_PNG:
                return "png";
                break;    
            default:
                return false;
                break;
        }
    }
    

    参考

    Lnng
    Cnblogs
    知乎
    先知社区
    CSDN-1
    CSDN-2

  • 相关阅读:
    NetCore DockerDesktop 踩坑记录
    VS2019 docker desktop 调试 vsdbg下载出错。
    Git 操作
    SQLServer远程连接失败的问题
    Echarts dataZoom缩放功能参数详解:
    flex布局
    解决vue项目中使用/deep/报错
    vue上传图片或文件
    github连接超时,经常打不开的问题
    vue2.0与vue3.0 双向数据绑定的理解
  • 原文地址:https://www.cnblogs.com/hugboy/p/upload_labs.html
Copyright © 2011-2022 走看看