upload-labs通关手册(1-9关)加代码审计

upload-labs通关手册

  • 前言
  • 一、文件上传
  • 二、通关手册
    • 1.pass-01(客户端js检查)
      • 源码分析
      • 通关方法
    • 2.pass-02(服务端白名单之MIME绕过 )
      • 代码分析
      • 通关方法
    • 3.pass-03(服务端黑名单之特殊解析后缀)
      • 代码分析
      • 通关方法
    • 4.pass-04(服务端黑名单之.htaccess解析)
      • 代码分析
      • 通关方法
    • 5.pass-05(服务端黑名单之大小写绕过)
      • 代码分析
      • 通关方法
    • 6.pass-06(服务端黑名单之空格绕过)
      • 源码分析
      • 通关方法
    • 7. pass-07(服务端黑名单之点绕过)
      • 源码分析
      • 通关方法
    • 8.pass-08(服务端黑名单之::$DATA绕过)
      • 源码分析
      • 通关方法
    • 9.pass-9(服务端黑名单之双写绕过)
      • 通关方法


前言

upload是基于文件上传漏洞的一个靶场,在里面可以学习到文件上传的一些常见方法

一、文件上传

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

后缀名:

有白名单和黑名单之分(白名单就是规定允许上传的后缀名格式,黑名单是规定不允许上传的后缀名格式)

文件类型:

对MIME信息的判断

文件头:

内容头信息的判定

二、通关手册

1.pass-01(客户端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;
    }
}

源码分析

第一关通过分析源码 "var allow_ext = ".jpg|.png|.gif";"可以得出则是对后缀名进行白名单的判断这里只要是客户端js的检测

通关方法

这里我们可以先将php文件改为jpg文件上传进行抓包上传后在对jpg后缀改为php
upload-labs通关手册(1-9关)加代码审计_第1张图片


2.pass-02(服务端白名单之MIME绕过 )

源码如下:

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

代码分析

“isset”:用于检测变量是否已设置并且非 NULL

if (isset($_POST['submit']))就是指有没有点击上传

file_exists(UPLOAD_PATH)UPLOAD_PATH是对上传路径的规定,这句代码的意思就判断这个上传路径的文件是否存在

if (($_FILES['upload_file']['type'] == 'image/jpeg') || ($_FILES['upload_file']['type'] == 'image/png') || ($_FILES['upload_files']['type'] == 'image/gif'))判断文件类型是否为image/jpeg或者image/png或者image/gif

$img_path = UPLOAD_PATH . '/' . $_FILES['upload_file']['name']规定文件路径为UPLPAD_PATH./加上文件名

move_uploaded_file($temp_file, $img_path)将文件移动到文件上传的路径中

通关方法

upload-labs通关手册(1-9关)加代码审计_第2张图片
在这里插入图片描述

抓包后发现这个文件类型与规定的都不一样所以就无法进行上传

这里我们只要修改上传文件的格式就可以达到文件上传

在这里插入图片描述
选取一个规定中的文件类型更改就可以上传成功
upload-labs通关手册(1-9关)加代码审计_第3张图片


3.pass-03(服务端黑名单之特殊解析后缀)

源码如下

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

代码分析

$deny_ext = array('.asp','.aspx','.php','.jsp');规定拒绝的后缀名

$file_name = trim($_FILES['upload_file']['name']);trim就是去除空格如果文件名中有空格就去除(这里的文件名就是抓包中的file_name)

$file_ext = strrchr($file_name, '.');strrch就是分割的意思将第一个参数按第二个参数进行分割输出后面的值

if(!in_array($file_ext, $deny_ext))判断你上面获取的file_ext在不在deny_ext(禁止上传后缀名中)不在的话就在继续执行下面上传代码

通关方法

php可以通过php5,php3进行上传(前提在apache的配置文件中将php3,5的注释去掉)所以这里可以直接将后缀名改为php3或php5这俩个不在黑名单中的后缀上传并同时可以达到执行php代码的要求
upload-labs通关手册(1-9关)加代码审计_第4张图片


4.pass-04(服务端黑名单之.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",".ini");
        $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","
相对第三关黑名单的数量增多其余代码没有变化

通关方法

htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置(前提要在apache下),为apache的平台做伪静态的转换,实现文件解析自定义

<FilesMatch "shana">
SetHandler application/x-httpd-php
</FilesMatch>
#对文件进行匹配如果发现文件名中shana就将其以application/x-httpd-php格式执行

将该文件上传之后就会将目录下的文件名中带shana的文件都已php格式执行
upload-labs通关手册(1-9关)加代码审计_第5张图片
将上传文件中的加入php代码并将文件名改为shana.jpg然后上传
upload-labs通关手册(1-9关)加代码审计_第6张图片

上传之后访问就会以php的格式执行
upload-labs通关手册(1-9关)加代码审计_第7张图片


5.pass-05(服务端黑名单之大小写绕过)

源码如下


代码

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

代码分析

$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_ext = strtolower($file_ext); 来转换为小写
所以直接后缀名携程大小写即可
upload-labs通关手册(1-9关)加代码审计_第8张图片
上传成功
upload-labs通关手册(1-9关)加代码审计_第9张图片

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

源码分析

这个关卡的源码都和之前一样知识缺少了首尾去空的一行代码

$file_ext = trim($file_ext); //首尾去空

通关方法

由于少了首位去空只要在文件名后加一个空格就可以进行绕过因为黑名单中并没有“.php ”的声明,上传后存储文件后又会自动去除空格
upload-labs通关手册(1-9关)加代码审计_第10张图片

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

源码分析

这个代码中少了删除文件末尾点的代码

$file_name = deldot($file_name);

通关方法

只要在文件名之后加一个‘.’就可以做到绕过
upload-labs通关手册(1-9关)加代码审计_第11张图片

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

源码分析

这里少了对字符串::$DATA的绕过

$file_ext = str_ireplace('::$DATA', '', $file_ext);

通关方法

 ::$DATA是windows下对于php文件的一种定义,如果在文件名之后加上::$DATA就会不对后缀名进行检测保持::$DATA之前的文件名

upload-labs通关手册(1-9关)加代码审计_第12张图片

9.pass-9(服务端黑名单之双写绕过)

源码如下:

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


通关方法

这里涉及到一个循环的问题
当这里涉及到比如deldot对末尾点的过滤式代码中只进行了一次过滤那我们就可以考虑加2个点之后被过滤掉一个空格从“.php..”变为了“ php.”这里就任然可以绕过黑名单进行上交并执行php文件内容

你可能感兴趣的:(安全)