upload-labs代码审计 1-12

uploadfile代码审计1-5

Pass-01

本关审计要点

主要了解前端JS函数功能是如何对上传文件进行检测的

源码

源码

function checkFile() {
    //var 为js定义变量的关键字 
    //document 用来调用功能点函数实现具体功能的
    //getElementsByName 方法返回带有指定名称的对象的集合,查询的是name属性的值
    //定义一个file变量去获取上传的文件名,比如:9z1nc.jpg 第1个元素:9z1nc
    var file = document.getElementsByName('upload_file')[0].value;
    //如果file 文件为null或者空,弹出提示,返回false。
    if (file == null || file == "") {
        alert("请选择要上传的文件!");
        return false;
    }
    //定义允许上传的文件类型
    var allow_ext = ".jpg|.png|.gif";
    //提取上传文件的类型
    //lastIndexOf 从.开始向后匹配
    //substring 提取.后的字符串
    //将提取到的后缀名赋值给ext_name
    var ext_name = file.substring(file.lastIndexOf("."));
    //判断上传文件类型是否允许上传
    //ext_name + "|"与.jpg|进行对比  不相同则返回-1 弹出errMsg
    if (allow_ext.indexOf(ext_name + "|") == -1) {
        var errMsg = "该文件不允许上传,请上传" + allow_ext + "类型的文件,当前文件类型为:" + ext_name;
        alert(errMsg);
        return false;
    }
}

allow_ext.indexOf(ext_name + "|") == -1

只要有.jpg|.png|.gif 就可以被匹配上

在这里插入图片描述

漏洞利用

利用思路

js前端校验,在代码中是获取上传数据包 Content-Disposition: form-data; name="upload_file"; filename="9z1nc.jpg" Content-Disposition字段中的filename元素内容取它的后缀.jpg与allow_ext中的内容对比,正确即可上传,抓包后只需要修改filename=“9z1nc.jpg” 为"9z1nc.php"就可以利用了。

使用蚁剑生产php webshell,先将文件改成.jpg格式上传并使用burp抓包

在这里插入图片描述

在burp中修改后缀为php

在这里插入图片描述

找到当前上传的路径

在这里插入图片描述

成功访问

在这里插入图片描述

Pass-02

本关审计要点

主要关注代码中对文件类型的判断

源码

$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类型是否为image/jpeg,image/png,image/gif 中的一个,如果是则上传成功,不是则弹出提示。我们只需要抓包后修改content-type类型为这3个白名单中的任意一个即可上传成功。

原来content-type类型为Content-Type: application/ocatet-stream

在这里插入图片描述

修改为image/png

在这里插入图片描述

成功上传

在这里插入图片描述

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

漏洞利用

利用思路

在代码中可以看到,采用了黑名单的方式定义了一些不可以上传的后缀名(‘.asp’,‘.aspx’,‘.php’,‘.jsp’)和处理掉了一些绕过方式(apache解析漏洞,windows文件流,大小写,双文件名)。但我们还可以利用其他的后缀名绕过代码的检测(php3、 php4、php5、pht、phtml、phps)

这里我们上传一个php5的文件,成功上传。

解析还需要改配置文件,这里就演示一下上传成功的效果

在这里插入图片描述

Pass-04

本关审计要点

本关主要关注move_uploaded_file()函数在上传文件时的移动操作

源码

$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 黑名单后缀比较齐全,file_ext也过滤掉了一些绕过方式,但问题出现在$img_path = UPLOAD_PATH.'/'.$file_name; 文件上传后并没有进行重命名的操作,直接将文件保存到相应的路径。我们则可以先上传.htaccess文件(apache中才有),将白名单中的文件当做Php来解析。

.htaccess(看网上说要上传到网站根目录下才能执行,这里直接上传到当前路径下也可以被解析)

将png文件当做php来解析

AddHandler application/x-httpd-php .png

在这里插入图片描述

Pass-05

本关审计要点

了解.user.ini在文件上传中的作用

源码

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

漏洞利用

利用思路

.user.ini文件是由用户自定义的php.ini文件,而我们可以利用auto_prepend_file与auto_append_file 可以在不改动任何页面的情况下,当需要修改顶部或底部require文件时,只需要修改auto_prepend_file与auto_append_file的值即可。

auto_prepend_file 在页面顶部加载文件

auto_append_file 在页面底部加载文件

可以看到黑名单也禁止了上传htacess文件,我们可以尝试上传.user.ini文件指定去包含xxx.png文件,而.user.ini文件它可以在php文件被执行的时候,去包含一个指定的文件当做代码执行,相当于require。

.user.ini

auto_prepend_file=9z1nc_5.png

这里需要注意 php要修改为非线程安全nts版本,还有测试的时候发现 是在执行上传路径中的php 会被包含成功

在这里插入图片描述

在这里插入图片描述

uploadfile代码审计6-11

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

漏洞利用

利用思路

代码中未使用strtolower()函数对上传的文件名后缀进行小写转换,所以我们可以通过大小写后缀绕过黑名单。

上传文件为9z1nc.pHP

在这里插入图片描述

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

漏洞利用

利用思路

代码中未使用trim()函数对上传文件的后缀名进行收尾去空,我们可以上传文件名为 9z1nc_7.php 的文件

在这里插入图片描述

访问成功

在这里插入图片描述

本地测试的时候发现 php版本7.1.9以上开始就会出现上传出错

在这里插入图片描述

Pass-08

本关审计要点

仔细查看过滤逻辑,以及过滤中用到的函数。

源码

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

漏洞利用

利用思路

代码中未使用deldot()函数删除上传文件后缀末尾的.,我们可以上传9z1nc.php.文件,而windwos在读取文件的时候会去掉末尾的.号,上传文件时候php.绕过了代码的过滤,.号windows会自己去掉,所以可以成功访问到自己的webshell

在这里插入图片描述

上传成功(php 5.6.9) php7.4.30上传失败

在这里插入图片描述

Pass-09

本关审计要点

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

漏洞利用

利用思路

:: D A T A W i n d o w s 会将 : : DATA Windows会将:: DATAWindows会将::DATA当成文件流来处理

例如:"9z1nc_9.php::$DATA"Windows会自动去掉末尾的::$DATA变成"9z1nc_9.php"

代码中未对:: D A T A 进行过滤,我们可以通过 : : DATA进行过滤,我们可以通过:: DATA进行过滤,我们可以通过::DATA绕过代码的限制,上传我们的webshell

在这里插入图片描述

上传成功,上传到服务器的文件在Windows中会自动去掉::$DATA

在这里插入图片描述

Pass-10

本关审计要点

仔细查看过滤逻辑,以及str_ireplace()函数的作用。

源码

$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); //转换为小写
        //str_ireplace  将::$DATA替换为空=去除字符串::$DATA
        $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变量并且使用trim()函数去掉上传文件名两边的空格再使用deldot()函数删除文件名末尾的点号;strrchr()函数处理filename变量获取到的文件名,取最后一次.号到后面的字符串赋值给file_ext 变量,接着对file_ext 变量进行转换为小写,去除字符串::$DATA,首尾去空的操作。这里还有一个问题就是未对上传的文件名进行重命名的操作,导致成功上传

​ 通过以上的代码逻辑,我们发现可以上传 名为**9z1nc.php.**空格. 的文件即可绕过代码逻辑,最后经过代码的处理 文件名为 9z1nc.php.

在这里插入图片描述

在这里插入图片描述

Pass-11

本关审计要点

仔细查看过滤逻辑,以及str_ireplace()函数的作用。

源码

$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","ini");

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

漏洞利用

利用思路

​ 代码中的逻辑问题,$file_name = str_ireplace($deny_ext,"", $file_name);将deny_ext定义的黑名单文件名进行替换为空“”,也就是我们上传9z1nc_11.php会变成9z1nc。但该代码逻辑并没有循环的去处黑名单后缀名,所以我们可以上传9z1nc_11.pphphp进行绕过。

在这里插入图片描述

在这里插入图片描述

uploadfile代码审计12-16

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

漏洞利用

利用思路

​ strrpos() 函数查找字符串在另一字符串中最后一次出现的位置。echo strrpos("Hello world",w)+1; //6。substr() 函数返回字符串的一部分。echo substr("Hello world",6);//word。$file_ext = substr($_FILES['upload_file']['name'],strrpos($_FILES['upload_file']['name'],".")+1);如果我们的上传文件名为demo.php。strrpos($_FILES['upload_file']['name'],".")+1 获取.号的下标为5,取到后缀名php。in_array( f i l e e x t , file_ext, fileext,ext_arr)函数搜索数组ext_arr中是否存在指定的值$file_ext。

我们将filename 修改为9z1nc_12.jpg绕过白名单校验,在通过get请求上传文件名为9z1nc_12.php%00

​ 由于在get传参时%00会被url编码转义一次变成0x00,而路径中如果遇到0x00空白字符会丢弃后面的内容

/upload/Pass-12/index.php?save_path=…/upload/9z1nc_12.php%00

filename=“9z1nc_12.jpg”

在这里插入图片描述

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值