phpcms v9文件上传的四次绕过复现

首先搭建测试环境,测试网站是否成功
在这里插入图片描述
首页代码

<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>文件上传章节练习题</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    <style type="text/css">
        .login-box{
            margin-top: 100px;
            height: 500px;
            border: 1px solid #000;
        }
        body{
            background: white;
        }
        .btn1{
            width: 200px;
        }
        .d1{
            display: block;
            height: 400px;
        }
    </style>
</head>
<body>
    <form method="post" action="upload.php" enctype="multipart/form-data">
        <input type="file" name="file" value=""/>
        <input type="submit" name="submit" value="upload"/>
    </form>
</body>
</html>

第一次漏洞:


<?php
header("Content-Type:text/html; charset=utf-8");
require_once('pclzip.lib.php');

function check_dir($dir)
{
    $handle = opendir($dir);
    while (($f = readdir($handle)) !== false) {
        if (!in_array($f, array('.', '..'))) {
            $ext = strtolower(substr(strrchr($f, '.'), 1));
            if (!in_array($ext, array('jpg', 'gif', 'png'))) {
                unlink($dir . $f);
            }
        }
    }
}

$file = $_FILES['file'];
if (!$file) {
    exit("请勿上传空文件");
}
$name = $file['name'];
$dir = 'upload/';//将上传的文件放到upload文件夹下面,后面查找文件的时候可以在upload文件夹下进行查找
$ext = strtolower(substr(strrchr($name, '.'), 1));//截取.后面的后缀名称。

$temp_dir = $dir . 'member/1/';
if (!is_dir($dir)) {
    mkdir($dir);
}

$temp_dir = $dir . 'member/1/';//这里是默认了创建目录为member下面,这个1实际上代表的是用户id,也就是每个用户都有一个自己的id
if (!is_dir($temp_dir)) {
    mkdir($temp_dir);
}

if (in_array($ext, array('zip', 'jpg', 'gif', 'png'))) {
    if ($ext == 'zip') {
        $archive = new PclZip($file['tmp_name']);//这里就是解压缩
        if ($archive->extract(PCLZIP_OPT_PATH, $temp_dir, PCLZIP_OPT_REPLACE_NEWER) == 0) {
            check_dir($dir);
            exit("解压失败");
        }
        check_dir($temp_dir);
        exit('上传成功!');
    } else {
        move_uploaded_file($file['tmp_name'], $temp_dir . '/' . $file['name']);
        check_dir($temp_dir);
        exit('上传成功!');
    }
} else {
    exit('仅允许上传zip、jpg、gif、png文件!');
}

但是在这个里面有一个问题,就是它没有进行递归删除,而是直接删除第一个文件夹里面的内容。
好比说:我新创建一个文件夹,里面包含了一张图片和一个包含一句话木马的php文件,但是在上传之后它会将php的文件删除,
这个2的文件夹里放的东西为:
在这里插入图片描述
将他进行压缩为zip的压缩包,然后进行上传。
在这里插入图片描述
上传成功后,我们在xss_location\upload\member\1的路径下可以看到,它是只有一个图片的,而那个php后缀的文件已经被删除了。
在这里插入图片描述
但是我们如果在文件夹中在进行一个嵌套,也就是在文件夹中在创建一个名为aaa的文件夹,将php文件放到aaa的文件夹当中,它就不会将php文件进行删除了。
也就是说当我们上传完文件之后,upload\member\1路径下中是存在aaa的文件夹,并且点进去之后,它是没有将咱们上传的php文件进行删除。
在这里插入图片描述

第二次漏洞

因为上面的漏洞被很多人发现,所以它想办法弥补,也就是说,我创建一个递归,即便有在多的文件,我也进去给你删除,所以代码就变成了:


<?php
header("Content-Type:text/html; charset=utf-8");
require_once('pclzip.lib.php');

function check_dir($dir){
    $handle = opendir($dir);
    while(($f = readdir($handle)) !== false){
        if(!in_array($f, array('.', '..'))){
            if(is_dir($dir.$f)){
                check_dir($dir.$f.'/');
             }else{
                $ext = strtolower(substr(strrchr($f, '.'), 1));
                if(!in_array($ext, array('jpg', 'gif', 'png'))){
                    unlink($dir.$f);
                }
            }
        }
    }
}

$file = $_FILES['file'];
if (!$file) {
    exit("请勿上传空文件");
}
$name = $file['name'];
$dir = 'upload/';
$ext = strtolower(substr(strrchr($name, '.'), 1));

if (!is_dir($dir)) {
    mkdir($dir);
}

$temp_dir = $dir . 'member/1/';
if (!is_dir($temp_dir)) {
    mkdir($temp_dir);
}

if (in_array($ext, array('zip', 'jpg', 'gif', 'png'))) {
    if ($ext == 'zip') {
        $archive = new PclZip($file['tmp_name']);
        if ($archive->extract(PCLZIP_OPT_PATH, $temp_dir, PCLZIP_OPT_REPLACE_NEWER) == 0) {
            check_dir($dir);
            exit("解压失败");
        }
        check_dir($temp_dir);
        exit('上传成功!');
    } else {
        move_uploaded_file($file['tmp_name'], $temp_dir . '/' . $file['name']);
        check_dir($temp_dir);
        exit('上传成功!');
    }
} else {
    exit('仅允许上传zip、jpg、gif、png文件!');
}

跟上一个不同的就是,我将解压后的文件夹放进一个递归里面,如果你文件夹中还有并且里面包含php文件,我也进行一个删除,但是,在它的写法中存在了一个逻辑错误,它是先进行查找,查找到之后就进行删除,那么就可以在它查到但是没有删除的这一个时间里面,我在写入一个php文件,即便它删除了我上传的,但是我新写入的那个是没有删除的,这也就是要采取一个时间竞争的关系来写入文件。
那么,咱么就需要修改一下php文件里面的内容
在这里插入图片描述
修改过后后,重新压缩,然后打开burp suite来进行抓包,然后时间竞争。
首先配置代理,
在这里插入图片描述
在这里插入图片描述
打开burp,在这里配置和刚刚在设置里面一样的ip和端口号。然后选择running,
在这里插入图片描述
先将抓包进行关闭,然后我们上传好文件的时候就可以进行开启抓包,抓包成功后,我们右键将他放到intruder里面,然后先清除,然后在随意找到一个数字添加。
在这里插入图片描述
之后在在paylods里面设置形式为数字,从1次到1000次,step为1 的访问。并且开始运行。
在这里插入图片描述
运行结束后可以在upload\member\1下去找是否成功。

第三次漏洞

因为上一个漏洞使用时间竞争就可以进行绕过,所以它对这个又进行了一次修改,也就是说将名称用一段随机数来替代,这样的话你就没有办法去寻找文件位置。那样的话就没有办法进行时间竞争。
所以将代码改成了:

<?php
header("Content-Type:text/html; charset=utf-8");
require_once('pclzip.lib.php');

function check_dir($dir){
    $handle = opendir($dir);
    while(($f = readdir($handle)) !== false){
        if(!in_array($f, array('.', '..'))){
            if(is_dir($dir.$f)){
                check_dir($dir.$f.'/');
             }else{
                $ext = strtolower(substr(strrchr($f, '.'), 1));
                if(!in_array($ext, array('jpg', 'gif', 'png'))){
                    unlink($dir.$f);
                }
            }
        }
    }
}

$file = $_FILES['file'];
if (!$file) {
    exit("请勿上传空文件");
}
$name = $file['name'];
$dir = 'upload/';
$ext = strtolower(substr(strrchr($name, '.'), 1));

$temp_dir = $dir.md5(time(). rand(1000,9999)).'/';//以随机数的方式来创建文件名称。
if (!is_dir($dir)) {
    mkdir($dir);
}


if (!is_dir($temp_dir)) {
    mkdir($temp_dir);
}

if (in_array($ext, array('zip', 'jpg', 'gif', 'png'))) {
    if ($ext == 'zip') {
        $archive = new PclZip($file['tmp_name']);
        if ($archive->extract(PCLZIP_OPT_PATH, $temp_dir, PCLZIP_OPT_REPLACE_NEWER) == 0) {
            check_dir($dir);
            exit("解压失败");
        }
        check_dir($temp_dir);
        exit('上传成功!');
    } else {
        move_uploaded_file($file['tmp_name'], $temp_dir . '/' . $file['name']);
        check_dir($temp_dir);
        exit('上传成功!');
    }
} else {
    exit('仅允许上传zip、jpg、gif、png文件!');
}

但是,这里也是存在一个bug,也就是所,如果我们进行解压缩,但是解压到一半的时候,让他解压出错,那么不就可以直接退出了吗,也就是说,解压一个错误的压缩包,那样就可以进行解压,但是因为它解压失败,所以就直接跳过了删除部分,直接结束,文件也就不会被删除。
在这里插入图片描述
那么如何让压缩文件解压出错?
首先:在window下的解压软件7zip;
7zip的容忍度很低,只要压缩包中某一个文件的CRC校验码出错,就会报错退出;所以我们就可以通过将校验码改错,它就不能正常解压缩。
在这里插入图片描述
这样的话我们在解压缩的时候它就会报错。
在这里插入图片描述
在php下使用自带的ZipArchive
以前我们在改文件的名字的时候,它会有一个提示:就是不允许出现一些符号,其中有一个是冒号(😃,那我们就可以将文件名字上加上那个,这样的话就可以解压失败。
我在那个D:\phpstudy_pro\Extensions\php\php7.3.4nts的路径下写了一个zip.php的文档,文档内容如下:

<?php
    function unzip($zipname,$path) {
        $zip = new ZipArchive;
        if(!$zip->open($zipname)) {//如果无法打开,报错
            echo "fail";
            return false;
        }

        if(!$zip->extractTo($path)) {//解压失败的话显示fail to extract
            echo "fail to extract";
            return false;
        }

        $zip->close();
        return true;
    } 

    if(unzip('./web.zip','./')) {//这个位置的web.zip是你要解压的文件名字,你要解压啥就写啥
        echo "success zip";
    }else {
        echo "failt to unzip";
    }

首先我们通过010 Editor这个软件来进行修改,将bbbb的后缀名从txt改成tx: ,
在这里插入图片描述
然后通过cmd来进行解压查看
在这里插入图片描述
我们回到文件中进行查找,可以看到php文件加载出来了,至于那个bbbb的文档就无所谓了,因为主要就是要用的这个。
在这里插入图片描述
至于LINUX下的错误解压方式我就不演示了,就只要记住,当文件名字是"\\"–也就是5个反斜杠的话,就会造成解压失败
所以刚刚那个漏洞就可以通过一个这样的错误的解压方式就可以进行绕过

第四次漏洞:

它发现又有人绕过了,它就又写出了一种方式,就是即便我解压失败了,我也要在进行一次递归查询,如果你这还有的话,我还是会给你删了。

<?php
header("Content-Type:text/html; charset=utf-8");
require_once('pclzip.lib.php');

$dir = 'upload/';
if (!file_exists($dir)) {
    mkdir($dir);
}

function check_dir($dir){
    $handle = opendir($dir);
    while(($f = readdir($handle)) !== false){
        if(!in_array($f, array('.', '..'))){
            if(is_dir($dir.$f)){
                check_dir($dir.$f.'/');
             }else{
                $ext = strtolower(substr(strrchr($f, '.'), 1));
                if(!in_array($ext, array('jpg', 'gif', 'png'))){
                    unlink($dir.$f);
                }
            }
        }
    }
}

$file = $_FILES['file'];
if (!$file) {
    exit("请勿上传空文件");
}
$name = $file['name'];
$dir = 'upload/';
$ext = strtolower(substr(strrchr($name, '.'), 1));


if (!is_dir($dir)) {
    mkdir($dir);
}

$temp_dir = $dir.md5(time(). rand(1000,9999)).'/';

if (!is_dir($temp_dir)) {
    mkdir($temp_dir);
}

if (in_array($ext, array('zip', 'jpg', 'gif', 'png'))) {
    if ($ext == 'zip') {
        $zip = new ZipArchive;
        if(!$zip->open($file['tmp_name'])) {
            echo "fail";
            return false;
        }
        if(!$zip->extractTo($temp_dir)) {
            check_dir($temp_dir);
            exit("fail to extract");
        }
        $archive = new PclZip($file['tmp_name']);

if ($archive->extract(PCLZIP_OPT_PATH, $temp_dir, PCLZIP_OPT_REPLACE_NEWER) == 0) {
            check_dir($dir);
            exit("解压失败");
        }
        check_dir($temp_dir);
        exit('上传成功!');
    } else {
        move_uploaded_file($file['tmp_name'], $temp_dir . '/' . $file['name']);
        check_dir($temp_dir);
        exit('上传成功!');
    }
} else {
    exit('仅允许上传zip、jpg、gif、png文件!');
}

那这种的话如何绕过呢?
这样的话我们就可以通过一个小技巧来进行绕过:制造一个特殊名称的webshell,…/…/…/…/web.php,当解压时,直接解压到根目录 随后,无论如何删除,也不能影响我们getshell
但是我们可以和上一个漏洞进行结合,它先解压失败,然后进行删除,而留下来的就是我们需要的php文件,这样的话我们就可以将使用刚刚说到的小技巧来将剩下的那个php留到上一个目录去,那样就可以了。
所以和上面的一样,我们通过010 editor来进行修改
在这里插入图片描述
然后上传文件进行测试,可以看到,它确实解压到前一个文件下面了。也就是保留了咱么的php文件。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PHPCMS v9 是一种流行的网站内容管理系统,用于创建和维护网站。它有一个功能强大的图片上功能,但目前是基于Flash的。然而,随着技术的发展和浏览器对Flash支持度的下降,越来越多的开发者将图片上功能改为HTML5。 将PHPCMS v9的图片上改为HTML5有许多好处。首先,HTML5支持跨平台和跨浏览器,几乎所有代浏览器都支持HTML5。相比之下,Flash对某些平台和设备的支持可能有限。其次,HTML5无需用户安装任何插件或软件,使得用户使用更加便捷。最后,使用HTML5可以提供更好的用户体验,例如拖放上、实时预览和进度条等。 要将PHPCMS v9的图片上改为HTML5,首先需要更新后端代码,以便支持新的上方式。PHP是PHPCMS的后端语言,可以使用PHP的文件函数来处理HTML5的文件。其次,需要更新前端代码,以便替换掉原来的Flash上组件。在HTML5中,可以使用input标签的type属性设置为file来创建一个文件表单控件,并使用JavaScript监听文件选择或拖放事件,实实时预览和进度条功能。 除了修改代码,还需要更改PHPCMS的配置文件,以便将上存储路径更改为服务器上合适的文件夹。同时,需要相应地更改数据库中存储图片信息的表结构,以适应新的图片上方式。 总结而言,将PHPCMS v9的图片上改为HTML5是一个重要的升级步骤,可以提供更好的用户体验和更广泛的平台兼容性。需要改动后端和前端代码,并相应地更新配置文件和数据库表结构。这样做可以使得网站更加代化和可访问,适应不断变化的技术环境。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值