MVC模式下的RCE漏洞代码审计-PHP
0x00 前置知识
MVC各层的职能:
1、控制器Controller层–负责响应用户请求、准备数据,及决定如何展示数据。
2、模块Model层–管理业务逻辑和数据库逻辑。提供连接和操作数据库的抽象层。
3、视图View层–负责前端模版渲染数据,通过HTML方式呈现给用户。
0x01 lmxCMS v1.4 RCE
寻找突破点:可以使用搜索法和功能点定位漏洞利用点。
1.1搜索法
https://www.cnvd.org.cn/flaw/show/CNVD-2019-05679
漏洞描述:LmxCMS V1.4后台Ac***.cl***.php存在代码执行漏洞
搜索关键词eval(),锁定AcquisiAction.class.php和Action.class.php这两个控制层的文件。

查看Action.class.php文件中eval()函数所在位置:

发现eval()函数是run()方法中的,根据注释,我们可以知道Action.clashh.php文件是控制层的代码,而run()方法是一个基类。想要执行eval('$this->'.$a.'();');这行代码,需要$a方法存在才可以,则变量$a不是一个可控变量,排除掉。再者,Action.class.php在这个CMS也算是一种配置文件,一般来说配置文件是没有漏洞的。
查看AcquisiAction.class.php中eval()函数所在位置

跟踪到eval()函数执行的变量是从 caijiDataOne($_GET['cid'])中来的,$cid是一个可控变量。继续跟踪caijiDataOne()方法,查看有无过滤。

发现在caijiDataOne()方法中的$param['where'] = 'id='.$id;代码中并没有对变量$cid进行过滤,而return parent::*oneModel*($param);代码是一个查询数据库的操作。
则可以确定$cid是一个可控变量。
回到AcquisiAction.class.php文件中,确定要满足什么条件才能触发eval('$data = '.$temdata['data'].'*;*');代码。

要赋值变量$lid, $id, $cid, 因为$GLOBALS[]是一个全局变量,所以$mid不需要赋值。
如何确定url地址,则我们要搞清楚这个CMS的路由是怎么样的。


index.php?m=content&a=index&classid=11&id=8
index.php---->权限(index/admin)
m=content---->控制层中 /c/index/ContentAction.class.php
a=index---->ContentAction.class.php中的index()方法
classid=11&id=8---->index()方法接收的参数

追踪Model层中的contents

跟踪View层的content---->/template/default/content/product.html


回到重点,怎么访问后台文件中的AcquisiAction.class.php中的showCjData()方法,参数有$id, $lid, $cid。
构造出: /admin.php?m=acquisi&a=showcjdata&id=1&lid=1&cid=1

数据库中data的值为1;phpinfo();//,访问http://192.168.11.1:81/admin.php?m=acquisi&a=showcjdata&id=1&lid=1&cid=1就可以得到一个phpinfo()界面,第一次的时候我可以的,后面不行了,在数据库中data的值一直写不进去。
实战中并不是这样子往数据库中写phpinfo(),在实战中是通过采集管理采集一个自定义网站,自定义网站写的就是data的值,则采集的数据就能写到数据库中去,去访问去触发利用就能成功。
1.2 功能点
https://www.cnvd.org.cn/flaw/show/CNVD-2019-05678
漏洞描述:LmxCMS V1.4后台Te***.cl***.php存在代码执行漏洞。
找到是/c/admin/TemplateAction.class.php代码,根据注释,说是的模板文件。

来到模型管理

查看模板标签说明,发现<{php}> <{/php}> 标签里可以直接写php代码。尝试写<{php}> phpinfo();<{/php}> ,写在模板文件中的footer.html中,看是否会执行。


访问网站首页,发现在底部成功出现了phpinfo()信息,利用成功!

0x02 bajiaCMSv4.1.4 RCE
https://www.cnvd.org.cn/flaw/show/CNVD-2021-12800
漏洞描述:百家CMS微商城存在命令执行漏洞。
搜索system关键词,没有找到可控变量,全是一些声明。

换一下,搜索system(,出现了系统执行函数system(),跟进去,看是否有可控变量。

system('convert'.$quality_command.' '.$file_full_path.' '.$file_full_path);
system()函数里有两个参数,$quality_command, $file_full_path。

$quality_command是由$quality_command=' -quality '.intval($scal);得到的,而可控变量$scal被intval()函数过滤了,只能是数字,则$quality_command没有可突破点。
再来看$file_full_path变量,$file_full_path变量在if(!empty($settings['image_compress_openscale']))判断中,设置了$image_compress_openscale才能执行system()函数。 继续往前看,$file_full_path在file_save()方法中,是该方法的第四个变量。
跟踪file_save()方法:来到了/system/weixin/class/web/setting.php中

file_save($file['tmp_name'],$file['name'],$extention,*WEB_ROOT*."/".$file['name'],*WEB_ROOT*."/".$file['name'],false);,该file_save()被包含在if($extention=='txt')判断中。
而if($extention=='txt')被包含在if (!empty($_FILES['weixin_verify_file']['tmp_name'])) 判断中,到此已追踪完毕。

理一遍逻辑:
if (!empty($_FILES['weixin_verify_file']['tmp_name']))
--->
if($extention=='txt')
--->
file_save($file['tmp_name'],$file['name'],$extention,*WEB_ROOT*."/".$file['name'],*WEB_ROOT*."/".$file['name'],false);
--->
if(!empty($settings['image_compress_openscale']))
--->
system('convert'.$quality_command.' '.$file_full_path.' '.$file_full_path);
触发条件:
weixin_verify_file有值
image_compress_openscale有值
文件后缀名为txt。
$file_full_path=*WEB_ROOT*."/".$file['name']
image_compress_openscale 图像压缩开启规模
文件名为代码执行处。
emm,因为我搭不起来百家CMS。所以暂时还没有验证能否成功,还有路由关系我也还没搞。
0x03 新旧版对比工具
beyond compare
这个可以用来比较新旧版的具体不同之处在哪里,新版有改动的地方会有红颜色的字体来表示。这个方便我们去复现1Day,根据厂商给出的补丁找到旧版的1Day漏洞。


浙公网安备 33010602011771号