这次接着上次的分析:
前篇传送门: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也是够水的了。
最后于 17小时前 被孑狱天编辑 ,原因: