• 上传漏洞总结-upload-labs


    介绍:

    Upload-labs是一个所有类型的上传漏洞的靶场

    项目地址:https://github.com/c0ny1/upload-labs

    思维导图:

    小试牛刀:

    Pass-01

    客户端js检查

    思路将PHP后缀的文件,改为.jpg格式的,然后上传抓包,将后缀名改回去,改成.php后缀的格式,即可绕过前端JS的校验

     getshell

    Pass-02 

    直接上产PHP脚本文件,提示如下:

    绕过思路类型绕过: image/jpeg

    getshell

     

    pass-03

    黑名单绕过,禁止上传.asp|.aspx|.php|.jsp后缀文件!

    绕过思路:上传:.php3 .phtml

    具体原理

    <IfModule php5_module>

        PHPIniDir "C:/phpStudy-01/PHP/"

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

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

        AddType application/x-httpd-php-source .phps

    </IfModule>

    getshell

    pass-04

    黑名单绕过

     getshell

    原理:

    先来看一下apache的主配置文件httpd.conf,搜索“DefaultType”,就可以看到这么一段注释和默认配置:

    #
    # DefaultType: the default MIME type the server will use for a document
    # if it cannot otherwise determine one, such as from filename extensions.
    # If your server contains mostly text or HTML documents, "text/plain" is
    # a good value. If most of your content is binary, such as applications
    # or images, you may want to use "application/octet-stream" instead to
    # keep browsers from trying to display binary files as though they are
    # text.
    #10DefaultType text/plain

    DefaultType存在的意义是告诉apache该如何处理未知扩展名的文件,比如f4ck.xxx这样的文件,扩展名是xxx,这肯定不是一个正常的网页或脚本文件,这个参数就是告诉apache该怎么处理这种未知扩展名的文件。

    参数DefaultType的默认值是“text/plain”,也就是遇到未知扩展名的文件,就把它当作普通的txt文本或html文件来处理。

    测试一

    比如我将以下代码保存为f4ck.xxx  默认解析成文本

    测试二

    那么,对于文件内容为php代码的未知扩展名文件来说也是解析成文本

    对于f4ck.php.xxx,那么就会被以module方式运行php的apache解析,因为Apache认为一个文件可以拥有多个扩展名,哪怕没有文件名,也可以拥有多个扩展名。Apache认为应该从右到左开始判断解析方法的。如果最右侧的扩展名为不可识别的,就继续往左判断,直到判断到文件名为止。

    解决方案一

    在httpd.conf或httpd-vhosts.conf中加入以下语句,从而禁止文件名格式为*.php.*的访问权限:

    <FilesMatch ".(php.|php3.|php4.|php5.)">
    Order Deny,Allow
    Deny from all
    </FilesMatch>

    解决方案二

    如果需要保留文件名,可以修改程序源代码,替换上传文件名中的“.”为“_”:

    $filename = str_replace('.', '_', $filename);

     

    还可以上传:.htaccess

    内容为:SetHandler application/x-httpd-php

    然后更改PHP的后缀为:.gif 即可

     

    pass-05

    黑名单绕过 本pass禁止上传.php|.php5|.php4|.php3|.php2|php1|.html|.htm|.phtml|.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|.htaccess后缀文件!

    貌似没有.PHP结尾的文件,可以尝试下

    getshell

    pass-06

    黑名单机制,查看源码:

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

        }

    }

     没有对文件的末尾的空格进行处理,所以可以尝试绕过

    getshell

    pass-07

    黑名单机制

    查看源码

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

        }

    }

    可以尝试.php.xxx的方式绕过

    getshell

     

     

    pass-08

    黑名单绕过

    查看源码: 去除字符串::$DATA

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

        }

    }

    进行绕过:

    getshell

    pass-09

    黑名单绕过

    分析源码:

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

        }

    }

    绕过方式1

    *.php.xxx

    绕过方式2

    *.php. . (点+空格+点)

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

        }

    }

    尝试双写后缀名绕过: c99.pphphp 替换了.后面的PHP就剩下了c99.php了

    getshell

    pass-11

    备注:11 12管需要关闭magic_quotes_gpc=Off 函数

    引用的过程中只有在传递$_GET,$_POST,$_COOKIE时才会发生作用

    白名单

    源码:

    $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类型文件!";

        }

    }

    看到imge_path是拼接的,所以可以尝试%00 截断,关于截断大致说下原理:

    常见的截断上传有:0x00,%00,/00 截断的核心在于chr(0)这个字符,这个函数表示返回以数值表达式值为编码的字符,举个例,print chr(78) 结果是N,所以char(0)表示的ascll字符是null,当程序输出包含chr(0)变量时,chr(0)后面的数据会被截断,后面的数据直接忽略,导致漏洞产生。

    getshell

    pass-12

    截断上传

    $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类型文件!";

        }

    }

    分析:img_path依然是拼接的路径,但是这次试用的post方式,还是利用00截断,但这次需要在二进制中进行修改,因为post不会像get对%00进行自动解码

    空格的十六进制是20 ,讲0x20 改成0x00 也就是00

    getshell

    pass-13

    查看源码,要求上传图片木马

    function getReailFileType($filename){

        $file = fopen($filename, "rb");

        $bin = fread($file, 2); //只读2字节

        fclose($file);

        $strInfo = @unpack("C2chars", $bin);   

        $typeCode = intval($strInfo['chars1'].$strInfo['chars2']);   

        $fileType = '';   

        switch($typeCode){     

            case 255216:           

                $fileType = 'jpg';

                break;

            case 13780:           

                $fileType = 'png';

                break;       

            case 7173:           

                $fileType = 'gif';

                break;

            default:           

                $fileType = 'unknown';

            }   

            return $fileType;

    }

    $is_upload = false;

    $msg = null;

    if(isset($_POST['submit'])){

        $temp_file = $_FILES['upload_file']['tmp_name'];

        $file_type = getReailFileType($temp_file);

        if($file_type == 'unknown'){

            $msg = "文件未知,上传失败!";

        }else{

            $img_path = UPLOAD_PATH."/".rand(10, 99).date("YmdHis").".".$file_type;

            if(move_uploaded_file($temp_file,$img_path)){

                $is_upload = true;

            } else {

                $msg = "上传出错!";

            }

        }

    }

     

    通过读文件的前2个字节判断文件类型,因此直接上传图片马即可,制作方法:

    第一种方法:copy normal.jpg /b + shell.php /a webshell.jpg

    第二种方法:exiftool -Comment='<?php echo "<pre>"; system($_GET['cmd']); ?>' 1.jpg

    Pass-14

    图片头绕过

    具体操作如下:

    将PHP木马文件,改成*.php;.jpg

    抓包,给文件头部加上:GIF89a 图片头标识

     

    pass-15

    php_exif模块来判断文件类型,还是直接就可以利用图片马就可进行绕过

     

    Pass-16

    查看源码

    $is_upload = false;

    $msg = null;

    if (isset($_POST['submit'])){

        // 获得上传文件的基本信息,文件名,类型,大小,临时文件路径

        $filename = $_FILES['upload_file']['name'];

        $filetype = $_FILES['upload_file']['type'];

        $tmpname = $_FILES['upload_file']['tmp_name'];

        $target_path=UPLOAD_PATH.basename($filename);

        // 获得上传文件的扩展名

        $fileext= substr(strrchr($filename,"."),1);

        //判断文件后缀与类型,合法才进行上传操作

        if(($fileext == "jpg") && ($filetype=="image/jpeg")){

            if(move_uploaded_file($tmpname,$target_path))

            {

                //使用上传的图片生成新的图片

                $im = imagecreatefromjpeg($target_path);

                if($im == false){

                    $msg = "该文件不是jpg格式的图片!";

                    @unlink($target_path);

                }else{

                    //给新图片指定文件名

                    srand(time());

                    $newfilename = strval(rand()).".jpg";

                    $newimagepath = UPLOAD_PATH.$newfilename;

                    imagejpeg($im,$newimagepath);

                    //显示二次渲染后的图片(使用用户上传图片生成的新图片)

                    $img_path = UPLOAD_PATH.$newfilename;

                    @unlink($target_path);

                    $is_upload = true;

                }

            } else {

                $msg = "上传出错!";

            }

        }else if(($fileext == "png") && ($filetype=="image/png")){

            if(move_uploaded_file($tmpname,$target_path))

            {

                //使用上传的图片生成新的图片

                $im = imagecreatefrompng($target_path);

                if($im == false){

                    $msg = "该文件不是png格式的图片!";

                    @unlink($target_path);

                }else{

                     //给新图片指定文件名

                    srand(time());

                    $newfilename = strval(rand()).".png";

                    $newimagepath = UPLOAD_PATH.$newfilename;

                    imagepng($im,$newimagepath);

                    //显示二次渲染后的图片(使用用户上传图片生成的新图片)

                    $img_path = UPLOAD_PATH.$newfilename;

                    @unlink($target_path);

                    $is_upload = true;              

                }

            } else {

                $msg = "上传出错!";

            }

        }else if(($fileext == "gif") && ($filetype=="image/gif")){

            if(move_uploaded_file($tmpname,$target_path))

            {

                //使用上传的图片生成新的图片

                $im = imagecreatefromgif($target_path);

                if($im == false){

                    $msg = "该文件不是gif格式的图片!";

                    @unlink($target_path);

                }else{

                    //给新图片指定文件名

                    srand(time());

                    $newfilename = strval(rand()).".gif";

                    $newimagepath = UPLOAD_PATH.$newfilename;

                    imagegif($im,$newimagepath);

                    //显示二次渲染后的图片(使用用户上传图片生成的新图片)

                    $img_path = UPLOAD_PATH.$newfilename;

                    @unlink($target_path);

                    $is_upload = true;

                }

            } else {

                $msg = "上传出错!";

            }

        }else{

            $msg = "只允许上传后缀为.jpg|.png|.gif的图片文件!";

        }

    }

    综合判断了后缀名、content-type,以及利用imagecreatefromgif判断是否为gif图片,最后再做了一次二次渲染,绕过方法还是上传图片木马

     

    pass-17

    竞争条件:

    $is_upload = false;

    $msg = null;

    if(isset($_POST['submit'])){

        $ext_arr = array('jpg','png','gif');

        $file_name = $_FILES['upload_file']['name'];

        $temp_file = $_FILES['upload_file']['tmp_name'];

        $file_ext = substr($file_name,strrpos($file_name,".")+1);

        $upload_file = UPLOAD_PATH . '/' . $file_name;

        if(move_uploaded_file($temp_file, $upload_file)){

            if(in_array($file_ext,$ext_arr)){

                 $img_path = UPLOAD_PATH . '/'. rand(10, 99).date("YmdHis").".".$file_ext;

                 rename($upload_file, $img_path);

                 $is_upload = true;

            }else{

                $msg = "只允许上传.jpg|.png|.gif类型文件!";

                unlink($upload_file);

            }

        }else{

            $msg = '上传出错!';

        }

    }

    这里先将文件上传到服务器,然后通过rename修改名称,再通过unlink删除文件,因此可以通过条件竞争的方式在unlink之前,访问webshell。

    首先在burp中不断发送上传webshell的数据包

    pass-18

    分析源码:

    $is_upload = false;

    $msg = null;

    if (isset($_POST['submit']))

    {

        require_once("./myupload.php");

        $imgFileName =time();

        $u = new MyUpload($_FILES['upload_file']['name'], $_FILES['upload_file']['tmp_name'], $_FILES['upload_file']['size'],$imgFileName);

        $status_code = $u->upload(UPLOAD_PATH);

        switch ($status_code) {

            case 1:

                $is_upload = true;

                $img_path = $u->cls_upload_dir . $u->cls_file_rename_to;

                break;

            case 2:

                $msg = '文件已经被上传,但没有重命名。';

                break;

            case -1:

                $msg = '这个文件不能上传到服务器的临时文件存储目录。';

                break;

            case -2:

                $msg = '上传失败,上传目录不可写。';

                break;

            case -3:

                $msg = '上传失败,无法上传该类型文件。';

                break;

            case -4:

                $msg = '上传失败,上传的文件过大。';

                break;

            case -5:

                $msg = '上传失败,服务器已经存在相同名称文件。';

                break;

            case -6:

                $msg = '文件无法上传,文件不能复制到目标目录。';

                break;     

            default:

                $msg = '未知错误!';

                break;

        }

    }

    //myupload.php

    class MyUpload{

    ......

    ......

    ......

      var $cls_arr_ext_accepted = array(

          ".doc", ".xls", ".txt", ".pdf", ".gif", ".jpg", ".zip", ".rar", ".7z",".ppt",

          ".html", ".xml", ".tiff", ".jpeg", ".png" );

    ......

    ......

    ...... 

      /** upload()

       **

       ** Method to upload the file.

       ** This is the only method to call outside the class.

       ** @para String name of directory we upload to

       ** @returns void

      **/

      function upload( $dir ){

       

        $ret = $this->isUploadedFile();

       

        if( $ret != 1 ){

          return $this->resultUpload( $ret );

        }

        $ret = $this->setDir( $dir );

        if( $ret != 1 ){

          return $this->resultUpload( $ret );

        }

        $ret = $this->checkExtension();

        if( $ret != 1 ){

          return $this->resultUpload( $ret );

        }

        $ret = $this->checkSize();

        if( $ret != 1 ){

          return $this->resultUpload( $ret );   

        }

       

        // if flag to check if the file exists is set to 1

       

        if( $this->cls_file_exists == 1 ){

         

          $ret = $this->checkFileExists();

          if( $ret != 1 ){

            return $this->resultUpload( $ret );   

          }

        }

        // if we are here, we are ready to move the file to destination

        $ret = $this->move();

        if( $ret != 1 ){

          return $this->resultUpload( $ret );   

        }

        // check if we need to rename the file

        if( $this->cls_rename_file == 1 ){

          $ret = $this->renameFile();

          if( $ret != 1 ){

            return $this->resultUpload( $ret );   

          }

        }

       

        // if we are here, everything worked as planned :)

        return $this->resultUpload( "SUCCESS" );

      }

    ......

    ......

    ......

    };

    对文件后缀名做了白名单判断,然后会一步一步检查文件大小、文件是否存在等等,将文件上传后,对文件重新命名,同样存在条件竞争的漏洞。可以不断利用burp发送上传图片马的数据包,由于条件竞争,程序会出现来不及rename的问题,从而上传成功

    pass-19

    源码:

    $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($_POST['save_name']);

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

            $file_ext = pathinfo($file_name,PATHINFO_EXTENSION);

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

        }

    }

    此漏洞属于截断上传,上传的文件名用0x00绕过。改成*.php【二进制00】.1.jpg,上传文件名改成要自己定义

    参考:

    https://xz.aliyun.com/t/2435

  • 相关阅读:
    算数表达式二叉树
    Java汉诺塔算法
    Struts2中的设计模式ThreadLocal模式续
    Java基础知识总结(五)
    Java数组扩容算法及Java对它的应用
    Java Arrays.sort源代码解析
    Java字符串排列算法
    Java基础知识总结(三)
    SSIS OLE DB Source中执行带参数的存储过程
    Sql server中Collation conflict问题
  • 原文地址:https://www.cnblogs.com/hack404/p/10385049.html
Copyright © 2020-2023  润新知