21:WEB漏洞文件上传之后端黑白名单绕过

知识点

文件上传常见验证:后缀名,类型,文件头等

1.后缀名:黑名单,白名单

  • 黑名单:明确不让上传的格式后缀,比如asp,php,jsp,aspx,cgi,war等,但是黑名单易被绕过,比如上传php5,Phtml等
  • 白名单:明确可以上传的格式后缀,比如jpg,png,zip,rar,gif等,推荐白名单。

2.文件类型:MIME信息

  • content-type字段校验,可以通过抓包改包方式绕过

3.文件头:内容头信息

  • 每种类型的文件都有自己固定的文件头信息,比如GIF89a是git图片的文件头信息,可以通过手动在脚本文件前面增加文件头的方式绕过。

4.windows特性

  • windows下文件名不区分大小写,linux下文件名区分大小写
  • windows下ADS流特性,导致上传文件xxx.php::$DATA  =  xxx.php
  • windows下文件名结尾加入“.”、“空格”、“<”、“>”、“>>>”、“0x81-0xff”等字符,最终生成的文件均被windows忽略。

本课重点

案例:uploadlabs关卡分析

下载:https://github.com/c0ny1/upload-labs

  • 案例1:$_FILES['upfile']访问文件的有关信息
  • 案例2:Pass-02 MIME-Type验证
  • 案例3:Pass-3 黑名单绕过 特殊解析后缀
  • 案例4:Pass-4 .htaccess绕过
  • 案例5:Pass-5 大小写绕过
  • 案例6:Pass-6 后缀名空格绕过
  • 案例7:Pass-7 点绕过
  • 案例8:Pass-8 ::$DATA绕过
  • 案例9:Pass-9 点+空格+点绕过(循环递归过滤)
  • 案例10:Pass-10 双写绕过
  • 案例11:Pass-11 %00截断 GET请求
  • 案例12:Pass-12 %00截断 POST请求

案例1:PHP基础知识:若文件上传域的name属性值为upfile,则可以使用$_FILES['upfile']访问文件的有关信息。

  • $_FILES['upfile']['name']; //客户端上传文件的原名称,不包含路径
  • $_FILES['upfile']['type']; //上传文件的MIME类型
  • $_FILES['upfile']['tmp_name']; //已上传文件在服务器端保存的临时文件名,包含路径
  • $_FILES['upfile']['error']; //上传文件出现的错误号,为一个整数
  • $_FILES['upfile']['size']; //已上传文件的大小,单位为字节

案例2:Pass-02 MIME-Type验证

MIME(multipurpose Internet mail extensions)多用途互联网邮件扩展类型。是设定某种扩展名的文件用一种应用程序来打开的方式类型,当该扩展名文件被访问的时候,浏览器会自动使用指定应用程序来打开。多用于指定一些客户端自定义的文件名,以及一些媒体文件打开方式。

查看代码,系统校验了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值为符合条件的值即可绕过。

修改

上传成功。

附各类文件MIME_type对照表  

{".3gp",    "video/3gpp"},   
{".apk",    "application/vnd.android.package-archive"},   
{".asf",    "video/x-ms-asf"},   
{".avi",    "video/x-msvideo"},   
{".bin",    "application/octet-stream"},   
{".bmp",    "image/bmp"},   
{".c",  "text/plain"},   
{".class",  "application/octet-stream"},   
{".conf",   "text/plain"},   
{".cpp",    "text/plain"},   
{".doc",    "application/msword"},   
{".docx",   "application/vnd.openxmlformats-officedocument.wordprocessingml.document"},   
{".xls",    "application/vnd.ms-excel"},    
{".xlsx",   "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},   
{".exe",    "application/octet-stream"},   
{".gif",    "image/gif"},   
{".gtar",   "application/x-gtar"},   
{".gz", "application/x-gzip"},   
{".h",  "text/plain"},   
{".htm",    "text/html"},   
{".html",   "text/html"},   
{".jar",    "application/java-archive"},   
{".java",   "text/plain"},   
{".jpeg",   "image/jpeg"},   
{".jpg",    "image/jpeg"},   
{".js", "application/x-javascript"},   
{".log",    "text/plain"},   
{".m3u",    "audio/x-mpegurl"},   
{".m4a",    "audio/mp4a-latm"},   
{".m4b",    "audio/mp4a-latm"},   
{".m4p",    "audio/mp4a-latm"},   
{".m4u",    "video/vnd.mpegurl"},   
{".m4v",    "video/x-m4v"},    
{".mov",    "video/quicktime"},   
{".mp2",    "audio/x-mpeg"},   
{".mp3",    "audio/x-mpeg"},   
{".mp4",    "video/mp4"},   
{".mpc",    "application/vnd.mpohun.certificate"},          
{".mpe",    "video/mpeg"},     
{".mpeg",   "video/mpeg"},     
{".mpg",    "video/mpeg"},     
{".mpg4",   "video/mp4"},      
{".mpga",   "audio/mpeg"},   
{".msg",    "application/vnd.ms-outlook"},   
{".ogg",    "audio/ogg"},   
{".pdf",    "application/pdf"},   
{".png",    "image/png"},   
{".pps",    "application/vnd.ms-powerpoint"},   
{".ppt",    "application/vnd.ms-powerpoint"},   
{".pptx",   "application/vnd.openxmlformats-officedocument.presentationml.presentation"},   
{".prop",   "text/plain"},   
{".rc", "text/plain"},   
{".rmvb",   "audio/x-pn-realaudio"},   
{".rtf",    "application/rtf"},   
{".sh", "text/plain"},   
{".tar",    "application/x-tar"},      
{".tgz",    "application/x-compressed"},    
{".txt",    "text/plain"},   
 {".wav",    "audio/x-wav"},   
{".wma",    "audio/x-ms-wma"},   
{".wmv",    "audio/x-ms-wmv"},   
{".wps",    "application/vnd.ms-works"},   
{".xml",    "text/plain"},   
{".z",  "application/x-compress"},   
{".zip",    "application/x-zip-compressed"},   
{"",        "*/*"}   

案例3:Pass-3 黑名单绕过 特殊解析后缀

源码配置了黑名单,不允许上传.asp,.aspx,.php,.jsp后缀的文件

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

但apache服务器能够使用php解析.phtml .php3 .php5

前提是apache的httpd.conf中有如下配置代码

AddType application/x-httpd-php .php .phtml .php3 .php5

因此可以上传.phtml .php3 .php5文件,绕过黑名单

案例4:Pass-4 .htaccess绕过

源码配置了黑名单,拒绝了几乎所有有问题的后缀名,除了.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 . '文件夹不存在,请手工创建!';
    }
}

.htaccess作为局部变量成功作用于当前目录下文件的两个条件(1.启用AllowOverride,2.开启mod_rewrite模块)

修改httpd.conf:
1、Allow Override All
2、LoadModule rewrite_module modules/mod_rewrite.so

本关正好符合,因此先上传一个.htaccess文件,内容如下:

<FilesMatch "hello">
setHandler application/x-httpd-php
</FilesMatch>

作用是使当前目录下所有文件名包含“hello”字符串的文件当作php文件解析。

然后再上传一个hello.jpg文件,内容如下:

<?php phpinfo(); ?>

此时访问该文件web路径,服务器执行hello.jpg文件中的PHP代码。

htaccess上传漏洞前提条件:

  • 1、apache服务器。
  • 2、能够上传.htaccess文件,一般为黑名单限制。
  • 3、AllowOverride All,默认配置为关闭None。
  • 4、LoadModule rewrite_module modules/mod_rewrite.so #mod_rewrite模块为开启状态
  • 5、上传目录具有可执行权限。 

补充:.htaccess简介

  • .htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过htaccess文件,可以帮我们实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。
  • .htaccess文件(或者"分布式配置文件")提供了针对每个目录改变配置的方法,即在一个特定的目录中放置一个包含指令的文件,其中的指令作用于此目录及其所有子目录。
  • 启用.htaccess,需要修改httpd.conf,启用AllowOverride。一旦启用.htaccess,意味着允许用户自己修改服务器的配置,可能会导致某些意想不到的修改。安全起见,应该尽可能地避免使用.htaccess文件。

案例5:Pass-5 大小写绕过

源码相比于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",".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 . '文件夹不存在,请手工创建!';
    }
}

可以上传.PHP文件,绕过黑名单。

案例6:Pass-6 后缀名空格绕过

源码相较于pass-4、pass-5,没有对后缀名进行去空,利用windows特性,会自动去掉后缀名中最后的空格,因此可以后缀名加空格绕过。

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

可以在上传文件时,抓包,将文件后缀改为.php+空格,绕过黑名单。

原理是 服务器在校验黑名单时,校验的后缀名是.php+空格,由于.php+空格不在黑名单内,可以通过校验,而windows系统在保存文件时,会自动去掉后面的空格,因此文件最终保存在服务器上的后缀名为.php。(linux系统在保存文件时应该也会自动去除空格,可以自行测试一下?)

案例7:Pass-7 点绕过

源码相较于pass-4,没有删除文件名末尾的点,利用windows特性,会自动去掉后缀名中最后的”.”,可在后缀名中加”.”绕过。

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

案例8:Pass-8 ::$DATA绕过

源码相较于pass-4,没有对后缀名中的“::$DATA”进行过滤。在php+windows的情况下,如果文件名+“::$DATA”会把“::$DATA”之后的数据当成文件流处理,不会检测后缀名,且保持“::$DATA”之前的文件名。利用windows特性,可在后缀名后面加“::$DATA”绕过。

例如“phpinfo.php::$DATA” Windows会自动去掉末尾的“::$DATA”变成“phpinfo.php”。

$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 = strtolower($file_ext); //转换为小写
        $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 . '文件夹不存在,请手工创建!';
    }
}

使用burpsuite抓包在文件后缀加::$DATA绕过。

案例9:Pass-9 点+空格+点绕过(循环递归过滤)

源码相较于前几关,所有的过滤都有。貌似没有问题,但是所有的过滤仅一次,先删除文件名末尾的点(仅删除一次),然后再首尾去空,导致可以利用1.php+(点+空格+点)来绕过。

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

使用burpsuite抓包在文件后缀加“点+空格+点”绕过。

原理是1.php+(点+空格+点)上传时,

  • 首先,删除文件名末尾的点,变成1.php+点+空格,
  • 然后,通过strrchar函数来确认文件的后缀名为.php+点+空格,
  • 接着,将文件的后缀名转换为小写、去除字符串::$DATA、首尾去空,变成.php+点,
  • 最后,判断文件后缀名是否在黑名单内。由于“.php.”不在黑名单中,可以通过校验,而windows特性,保存文件时会自动去掉后缀名中最后的”.”,最终文件成功上传并保存为1.php。

案例10:Pass-10 双写绕过

黑名单过滤,将黑名单里的后缀名替换为空且只替换一次,因此可以用双写绕过

$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","jsp","jspa","jspx","jsw","jsv","jspf","jtml","asp","aspx","asa","asax","ascx","ashx","asmx","cer","swf","htaccess");

        $file_name = trim($_FILES['upload_file']['name']);
        $file_name = str_ireplace($deny_ext,"", $file_name);
        $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 = UPLOAD_PATH . '文件夹不存在,请手工创建!';
    }

使用burpsuite抓包将文件后缀改为.pphphp绕过。

案例11:Pass-11 %00截断

源码

$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
    $ext_arr = array('jpg','png','gif');
  //获取文件名最后一个点后面的字符串
    $file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1); 
    if(in_array($file_ext,$ext_arr)){
        $temp_file = $_FILES['upload_file']['tmp_name'];
        $img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;

        if(move_uploaded_file($temp_file,$img_path)){
            $is_upload = true;
        } else {
            $msg = '上传出错!';
        }
    } else{
        $msg = "只允许上传.jpg|.png|.gif类型文件!";
    }
}

白名单过滤,但$img_path是直接拼接而成,因此可以利用%00截断绕过。

$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;

截断条件:php版本小于5.3.4,php的magic_quotes_gpc为OFF状态

案例12:Pass-12 %00截断

源码

$is_upload = false;
$msg = null;
if(isset($_POST['submit'])){
    $ext_arr = array('jpg','png','gif');
    $file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);
    if(in_array($file_ext,$ext_arr)){
        $temp_file = $_FILES['upload_file']['tmp_name'];
        $img_path = $_POST['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;

        if(move_uploaded_file($temp_file,$img_path)){
            $is_upload = true;
        } else {
            $msg = "上传失败";
        }
    } else {
        $msg = "只允许上传.jpg|.png|.gif类型文件!";
    }
}

源码相较于pass-11,save_path参数通过POST方式传递

$img_path = $_POST['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;

还是利用%00截断,因为POST不会像GET对%00进行自动解码,所以需要在二进制中进行修改。

参考:

  • https://blog.csdn.net/weixin_44677409/article/details/92799366
  • https://www.cnblogs.com/adforce/archive/2012/11/23/2784664.html
  • 等等
原文地址:https://www.cnblogs.com/zhengna/p/15619664.html