web漏洞分析(2)之——zzcms多个cve分析
2019-08-29 15:43:53 Author: bbs.pediy.com(查看原文) 阅读量:219 收藏

这次接着上次的分析:

前篇传送门:web漏洞分析(1)之——CVE-2019-1010153

这次直接分析剩下四个RCE漏洞.说是四个,其实多数水出来的,真正的漏洞可以说是只有一个.漏洞编号分别是:

CVE-2019-1010148

CVE-2019-1010152

CVE-2019-1010150

CVE-2019-1010149

这里先选择最后一个

需要本文复现的cms附件在上一篇文章内。

此文章已同时发布至我新建的个人博客,欢迎围观。 ^_^

漏洞分析

好了,直接步入正题.漏洞之一发生在install/index.php中—这是cms应用安装文件.

使用seay打开zzcms的根目录.打开漏洞文件.

刚进来就看见两个extract()

if($_POST) extract($_POST, EXTR_SKIP)

if($_GET) extract($_GET, EXTR_SKIP);

遇见这个函数就要注意变量覆盖漏洞了(但这里没有)因为extract函数的flag参数设置的是EXTR_SKIP

flags

对待非法/数字和冲突的键名的方法将根据取出标记flags参数决定。可以是以下值之一:

EXTR_OVERWRITE

如果有冲突,覆盖已有的变量。

EXTR_SKIP

如果有冲突,不覆盖已有的变量。

EXTR_PREFIX_SAME

如果有冲突,在变量名前加上前缀prefix。

EXTR_PREFIX_ALL

给所有变量名加上前缀prefix。

EXTR_PREFIX_INVALID

仅在非法/数字的变量名前加上前缀prefix。

EXTR_IF_EXISTS

仅在当前符号表中已有同名变量时,覆盖它们的值。其它的都不处理。 举个例子,以下情况非常有用:定义一些有效变量,然后从$_REQUEST中仅导入这些已定义的变量。

EXTR_PREFIX_IF_EXISTS

仅在当前符号表中已有同名变量时,建立附加了前缀的变量名,其它的都不处理。

EXTR_REFS

将变量作为引用提取。这有力地表明了导入的变量仍然引用了array参数的值。可以单独使用这个标志或者在flags中用 OR 与其它任何标志结合使用。如果没有指定flags,则被假定为EXTR_OVERWRITE。

当flag为EXTR_OVERWRITE是可能会存在变量覆盖漏洞.

继续往下看,来到105-108行,

作用是打开 inc/config.php 并将响应相应的str值写入到文件.

但str变量中含有其他可控变量:

$str=str_replace("define('siteurl','".siteurl."')","define('siteurl','$url')",$str)

这一句中参数$url在文件之前并未初始化过,而之前又用extract函数将

将变量$url导入到当前的符号表,所所以url变量可控,这就导致了可向inc/config.php文件中写入任意代码.

二话不说,访问install/index.php文件看看:

果然不出所料,检测了安装锁文件.全局搜索一下””安装向导已运行安装过,如需重安装””字符串,发现在本文件安装第一步包含的文件中:

switch($step) {

case '1'://协议

include 'step_'.$step.'.php';

break;

进入step_1.php中:

if(file_exists("install.lock")){

echo "<div style='padding:30px;'>安装向导已运行安装过,如需重安装,请删除 /install/install.lock 文件</div>";

}

要想写入任意代码,必须删除install/install.lock文件.

然后我们先来看下一个漏洞文件——user/licence_save.php

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

}

}

}

}

当action=’modify‘,oldimg=$_POST[“oldimg”],接着删除由oldimg拼接的文件$fs,造成了任意文件删除漏洞。

思路

可以用任意文件删除漏洞删除安装锁文件即install/install.lock,再使用install/index.php文件的任意代码写入,最终写入并执行任意代码。

漏洞复现

首先post数据删除install.lock(我用的postman)

这里访问user/licence_save.php前要先注册用户(浪费了好长时间,不知道公司的名称格式,最后索性直接删了验证公司名称的代码):

访问过后,install/install.lock文件果然没有了。

接着访问http://127.0.0.1/install/index.php进行重装,接着就和上一篇一样,安装到第4步时,将

网站访问地址改为:(这个就是url参数):

http//:127.0.0.1');phpinfo();//

点击下一步,安装成功后可以看到:

已经在inc/config.php插入了代码;

再次访问http://127.0.0.1/inc/config.php:

可以看到代码已经成功执行了。

最后,我们再来看一下剩下的几个漏洞:

CVE-2019-1010150

在/user/zssave.php文件中:

$oldimg=trim($_POST["oldflv"]);

if ($oldflv<>$flv && $oldflv<>""){

$f="../".$oldflv;

if (file_exists($f)){

unlink($f); }

}

仅仅是一个任意文件删除,接下来依旧是利用上一个任意代码写入,而且是同样的文件,一样的套路……

CVE-2019-1010152

在user/manage.php中

$oldflv = isset($_POST['oldflv'])?$_POST['oldflv']:'';

if ($oldflv<>$flv){

$f="../".$oldflv;

if (file_exists($f)==true){

unlink($f);

}

依旧是一样的套路……

最后一个

CVE-2019-1010148

这个依旧是一样的

在/user/adv.php中

$oldimg=$_REQUEST["oldimg"];

if ($oldimg<>$img){

$f="../".$oldimg;

if (file_exists($f)){

unlink($f);

}

依旧是RCE,但cnnvd公布的是sql注入,估计他们也对这些水漏洞感到无奈了吧。

总结

这些漏洞其实RCE的只能算是一个,这个大佬为了刷cve也是够水的了。

[活动]走进企业看安全第22站--蚂蚁金服!

最后于 17小时前 被孑狱天编辑 ,原因:


文章来源: https://bbs.pediy.com/thread-254177.htm
如有侵权请联系:admin#unsafe.sh