梦想CMS注入漏洞分析&发现小彩蛋
ajie 漏洞分析 6253浏览 · 2021-11-03 15:47

0x01 前言

查资料的时候,偶然间看到这样一个漏洞,在一个提交表单的地方,插入SQL语句,便可以进行报错注入。看着有点像二次注入,对于这样类型的注入,我个人遇到的还是比较少的,再加上一般这种地方多数会尝试XSS,所以进行了分析,看看漏洞到底是如何产生的。

0x02 环境搭建

1、首先准备phpstudy,这里使用的是2016版本的,php版本为5.6.27

2、下载cms源码
cms下载地址:
http://www.lmxcms.com/file/d/down/xitong/20210628/202106281714266126.zip


3、访问http://192.168.150.8/install/进行安装

4、输入相应信息即可。
注意:需要提前创建好数据库

0x03 漏洞复现

1、访问http://192.168.150.8/admin.php?m=Login,输入账号密码进入后台

2、在采集管理功能处点击创建节点

3、payload如下:

1' and updatexml(0,concat(0x7e,database()),1) and '

4、经测试节点名字和备注均能够触发漏洞
1)备注功能点触发


2)节点名字功能点触发

0x04 漏洞分析

1、因为漏洞是sql注入,所以首先可以使用数据库语句监控工具进行监控执行的语句。这里我使用的是seay自带的数据库监控工具。

2、输入账号密码,点击下断

3、发送sql注入的数据包后,点击更新

4、可以看到是一个插入数据库的语句

INSERT INTO lmx_cj(name,mid,content) VALUES('11111111111111111111111','1','1' and updatexml(0,concat(0x7e,database()),1) and '')


5、后面的数据包中可以看到是进行了查询

6、这里很明显就是一个插入数据库的功能,将数据插入到lmx_cj表中,因为updatexml函数导致了报错。查看这个数据表,里面是没有数据的。

7、插入正常的字符串,里面成功添加了数据。


8、那么下面开始代码分析,从数据包中很明显可以看到访问的路径为admin.php?&m=Acquisi&a=add。分析过MVP框架的代码便可以很明显看出一个是对应的文件Acquisi,里面调用了add函数。
先来查看一下admin.php文件,里面包含了/inc/config.inc.php和/inc/run.inc.php两个文件。

9、分别打开2个文件查看,跟文件名上表示的一样,一个是配置,一个是路由


10、其中有一个地方值得注意一下,action即方法是放在根目录下或者extend/目录下的c文件夹中,同理model即模块是放在m文件夹中。

然后就是执行问题了,这里可以看到区分了伪静态和单入口,大体意思其实跟tp框架的很像,一者是/模板/方法/参数名/参数值,一者是/?m=模板&a=方法

看最后面

eval('$action=new '.$m.$extendEnt.'();');

这里就是可以定位到漏洞文件所在的地方,很明显传入的m的值为Acquisi,所以这个请求对应的类为AcquisiAction()
11、在/c/admin/AcquisiAction.class.php找到了它

12、在add方法中可以看到,其实就是检测了是不是有从post请求中传入add,并且在data中的name对应的值不为空。其中存在几个函数分别是d()、p()、add()

13、定位一下d()方法,使用foreach函数,数组键分别赋值,看前面可以知道fieldCj就是一个name,mid,content的数组;$type这里有一个很重要的(int)类型强制转换,$is_int为传入的数组mid,并且$v为mid时,将其进行强制转换,也就是post包中传入的mid固定为整型。


14、再看一下p()方法,$type=1,$_POST传入的数据赋值给$data;因为前面只传入了一个1,所以$pe、$sql、$mysql均为false;下面在代码注释中进行说明。

function p($type=1,$pe=false,$sql=false,$mysql=false){
    if($type == 1){
        $data = $_POST;  //进入这里
    }else if($type == 2){
        $data = $_GET;
    }else{
        $data = $type;
    }
    if($sql) filter_sql($data);             //过
    if($mysql) mysql_retain($data);     //过
    foreach($data as $k => $v){
        if(is_array($v)){               //未传入数组,过
            $newdata[$k] = p($v,$pe,$sql,$mysql);
        }else{
            if($pe){                        //过
                $newdata[$k] = string::addslashes($v);
            }else{
                $newdata[$k] = trim($v);    //首尾去空后赋值给数组newdata[]
            }
        }
    }
    return $newdata;
}


15、前面对数据处理完之后,调用了这个类的modle中的add()方法

$this->model->add($data);

所以我们需要在m文件夹中寻找Acquisi的model文件

16、打开一看,第一个函数add就是我们需要的

17、右键,选择定位函数(其实使用phpstorm快一点,奈何我这个是虚拟机,没有那个条件装那么大的软件)

18、很幸运,只有一个,不用进行筛选了

19、调用了一个新函数addDB,从字面上的意思理解是添加到数据库,继续定位函数


20、找到函数之后进行分析,首先将数据进行键值分离,然后存入到数组field[]和value[]中,关于implode()函数的用法,我百度了一下,可以理解为使用逗号将数组中的每个值进行连接。然后,就放入到sql语句中了。


21、然后是执行query函数,将sql语句直接执行,如果没有返回结果就将错误信息返回。

22、总结一下利用链
首先从admin.php文件 -> 再到/inc/run.inc.php文件 -> 然后调用了传入的m参数值AcquisiAction类 -> AcquisiAction类中的add() -> 对数据经过一些处理,调用了d()、p()函数 -> 调用AcquisiAction类对应的Model中的add方法 -> 调用addModel() -> 调用addDB() -> 在addDB方法中进行了数组的转换就直接放入到sql语句中 ->调用了query()方法,执行了sql语句,然后如果执行结果为空,则将错误打印出来。

23、分析之后我发现一个有意思的东西,既然没有经过任何过滤,那么是不是存在存储型XSS漏洞呢,试了一下,确实存在。

两个参数均存在。

0x05 总结

分析完一条完整的利用链了,漏洞利用那么简单,但是实际分析确实还是有一点难的,当然如果有PHPstrom可能会好一些,函数之间的跳转会方便点,并且可以通过截断数据进行debug调试,也比这样轻松。但是总的来说还是成功分析完了,这里其实有一些地方的分析还是存在不足之处的,也希望大家体谅小白对代码的熟练度还不够。
小彩蛋:
因为页面会直接返回错误语句,那么这里不就也存在XSS漏洞了?let me try try~

首先单引号让数据报错,然后后面插入xss payload
'<img src=1 onerror=alert(1)>


然后,在位置2它出现了~

查看了一下,位置1没有触发是因为<不见了

那么尝试一下闭合,成功触发。

')<img src=1 onerror=alert(1)>'



3 条评论
某人
表情
可输入 255