前言

文件上传靶场:https://codechina.csdn.net/mirrors/c0ny1/upload-labs/-/archive/master/upload-labs-master.zip

本系列文章是我在学习文件上传时写下的笔记,如有错误欢迎大家指出。

pass-1

查看源代码,可以发现进行了文件后缀过滤,只能上传.jpg/.png/.gif后缀的文件

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

前端进行了后缀拦截,只允许上传那三种后缀。

<?php
    phpinfo();
?>

将这个php文件改为png后缀,进行上传,burpsuite抓包,修改一下后缀

打开控制台可以看见路径,我们进行访问这个路径

可以看到php代码执行,绕过成功。

pass-2

先查看第二关源码,可以通过代码发现,检测的是Content-Type这个字段,故我们上传php文件时需要通过burpsuite来更改Content-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.'文件夹不存在,请手工创建!';
    }
}

用burpsuite进行抓包,可以抓到上传php脚本时的数据包,Content-Type这个字段为php文件的,我们将其改成源码允许的格式,image/png尝试放包

改成源码规定的格式,放包。查看浏览器控制台

可以看到浏览器控制台php脚本文件成功上传,接下来根据文件地址,用蚁剑连接

可以看到成功get shell,并可以看到文件目录。

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脚本改后缀用蚁剑连接,发现连接成功但是连查看的权限都没有,说明此套源码还对别的进行了检测。这里就要用到特殊的后缀.php3 .php5这两个特殊后缀

这里我踩了一个坑,我下载phpstudy的版本问最新版8.1版本,但是发现php3、php5、phtml后缀蚁剑都无法连接,就连上传一个.htaccess 都无法成功,起初是以为蚁剑的原因,直到我把冰蝎和菜刀都试了一遍然后上网找资料,看到了一篇更改php配置文件中更改这一段代码的文章,找了我的版本并没找到,我才意识到是phpstudy的问题。我重新下载了phpstudy2014版本,尝试一下,终于找到了这一段代码配置的地方

所以建议大家去下载安装版本不要太高的phpstudy来进行文件上传靶场的搭建。

将这一串配置文件改为如下配置,记得将#号去掉

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

接下来我们就将php一句话木马改为.php3后缀,这里我为了简单一点,将木马改成了暴露php配置

<?php
phpinfo();
?>

可以看到上传图片的路径,在地址栏输入该路径,成功绕过。

可以看到php代码执行成功,爆出了php的信息

5yklQK.md.png

pass-4

同样,附上源码

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

可以看到这套源码把几乎所有的拓展后缀都过滤掉了,这可如何是好?

这就得提到.htaccess这个种文件了.htaccess,我们需要修改一下Apache下面的httpd.conf配置文件。

可以看到我们这是不需要修改的,如果需要修改,只需要将none改为All

.htaccess可以帮我们实现包括:文件夹密码保护、用户自动重定向、自定义错误页面、改变你的文件扩展名、封禁特定IP地址的用户、只允许特定IP地址的用户、禁止目录列表,以及使用其他文件作为index文件等一些功能.

关于.htaccess文件的有关知识大家可以去百度一下,这里就不细讲。好,现在开始,新建一个文本文档。输入以下代码。这段代码的意思就是将所有文件都用php编译。写好后改为.htaccess后缀,上传。

上传成功,这时候再将原来的一句话php文件改为被允许上传的格式,同样会当作php文件被执行。

上传一句话php,上传成功

成功爆出php信息,绕过成功。

pass-5

源码,好家伙,.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 = 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改后缀为.php. .这个特殊后缀,也可以通过创建后缀为.user.ini这个文件来绕过,这个大家可以自己百度。

上传成功,查看控制台发现路径。

地址栏输入路径,访问。

成功爆出数据,绕过成功。