Duomicms_X2.0变量覆盖通杀漏洞复现


一、Duomicms简介

多米影视管理系统(DuomiCms,多米CMS)是一套专为不同需求的站长而设计的视频点播系统,灵活,方便,人性化设计简单易用是最大的特色,是快速架设视频网站首选,只需3分钟即可建立一个海量的视频讯息的行业网站。
DuomiCms采用PHP+MYSQL架构,原生PHP代码带来卓越的访问速度和负载能力免去用户的后顾之优。众多人性化功能设计,超前定时执行任务,让用户处理数据得心应手,因此用户只需要专心做内容运营即可。
为符合SEO要求开发大量功能,比如百度结构化数据生成,搜索引擎地图等。全新设计的专题管理,同时支持主分类,扩展分类,剧情分类三种分类方式,让网站内容与众不同。简单易用丰富的模板标签,方便网站模板设计制作,让网站更显专业。
总而言之,DuomiCms是基于PHP+MySql技术开发的影视管理系统,简单易用、制作模板方便,其构架稳健,可平滑升级,非常便利。


三、Duomicms_X2.0安装

首先通过百度搜索下载该cms,这里我忘记下载地址了,大家可以去百度自行搜索该cms,很好找。
我将文件夹改名为Duomicms,然后本地访问:

http://127.0.0.1/Duomicms/upload/install/

在这里插入图片描述
注意有时会出现高版本的配置无法安装的情况,因此我这里使用了5.2.17的php:
在这里插入图片描述
做好基本的设置后,会看到该页面:
在这里插入图片描述
此时已经安装完毕。

三、Duomicms源代码审计及漏洞复现

使用php语言开发的网站,寻找变量覆盖时重点找危险函数extract()或者parse_str() 。这里使用seay源代码审计工具搜索这两个函数:
在这里插入图片描述
在这里插入图片描述
发现没有使用这两个函数。难道它就没有变量覆盖漏洞了吗?非也。实际上,不仅仅是函数可能导致变量覆盖,有些特殊符号的搭配也会引起变量覆盖漏洞,比如$$。
看下面的例子:

<?php 
$a = 1; //预先进行变量赋值 
foreach(array('_COOKIE','_POST','_GET') as $_request) {
    
    
foreach($$_request as $_key=>$_value) {
    
    $$_key=addslashes($_value);
}} 
echo $a; 
?> 

这段代码的作用是: 将cookie、post、get传参分别拿出来,进行键值分离.使用foreach来遍历数组中的值,然后再将获取到的数组键名作为变量,数组中的值作为变量的值。
注意这里的request只是用户自己定义的一个普通的变量名而已,并不是用来接收POST或者GET传参的那个大写的REQUEST,注意二者的区别,大写和小写是完全不同的含义。
代码解释:

array('_COOKIE','_POST','_GET')//数组里面有三个字符串
foreach(array('_COOKIE','_POST','_GET') as $_request) 
foreach($$_request as $_key=>$_value)

这里foreach通过三次循环遍历数组中的值,然后再将获取到的数组键名作为变量,数组中的值作为变量的值。
这段代码会接受我们的GET传参、POST传参、COOKIE传参,将这个接受来的参数依次放入$_request中。
$_key=>$_value 这是个数组解析,实际上就是键值分离。
正常而言$a = 1是一个定值,但是因为$$_key的缘故,当我传参a=2;那么经过这行代码:
\$\$_key=addslashes($_value);
处理后,就变为了$a=2。
注意foreach里面的变量是全局变量,对整个程序都生效。

好了,言归正传,现在去源码中搜索$$:
在这里插入图片描述
发现有大量文件使用了这组特殊符号。
需要注意的是,访问目标站点时,很多文件是需要权限的,如果是要找前台的漏洞,基本上admin目录下的文件就不用看了,因为admin都是需要后台权限才可能利用这种漏洞。我们要找漏洞尽可能去比较通用的文件里找,比如后缀为以下这几种的就是通用的:
common.func.php
.func.php(开发可能把所有要用的函数全部写在一个文件里,需要的时候再去调用)
.class.php(里面可能定义了很多类)
.inc.php
这些文件要重点关注,可能很有用,因为大部分的文件都会加载这些文件。
这里重点查看common.php文件,发现了一个可能存在变量覆盖的地方:在这里插入图片描述
往上找,看一看使用这个变量覆盖需要满足的条件:

foreach($_REQUEST as $_k=>$_v)
{
    
    
	if( strlen($_k)>0 && m_eregi('^(cfg_|GLOBALS)',$_k) && !isset($_COOKIE[$_k]) )
	{
    
    
		exit('Request var not allow!');
	}
}

函数解释如下:

strlen()//返回字符串的长度 
m_eregi()//正则表达式 
isset()//当变量的值为 NULL或0时,返回 FALSE,否则返回TRUE 
exit()//类似die()函数,输出一条消息,并退出当前脚本,即代码执行到当前的位置后,输出字符串并停止执行程序

可见要想满足if的要求,需要满足以下三个条件:
1.必须要有传参;
2.键名有cfg_GLOBALS
3.COOKIE传参中没有键名。
当这三个条件都满足的时候就会进入if分支,然后执行exit就不再往下执行了。
我们很明确的知道了,只要不进入if分支,就可以通过common.php文件实现任意代码执行。那么我们去看下什么文件调用了他。
传统的方法就是一个个文件找过去,看看哪个调用了common.php,并且能不能利用。
但是这里我们有捷径,就是利用session来做。
考虑一下,什么情况下网站会设置session呢?至少在管理员登陆的时候肯定会吧?所以我们首先尝试从与登陆有关的文件里查找线索。
在后台登陆界面先抓个包分析一下看看登陆的过程会发生什么情况:
在这里插入图片描述
发现数据包会提交给login.php文件,放包看看还有没有其他数据包:
在这里插入图片描述
出现了一个跳转的页面,同时有一个数据包:
在这里插入图片描述
这个数据包是登陆成功后跳转页面的,可见admin目录下的login.php就是负责控制登陆过程的。在seay中查找该文件,分析代码,看到有keepUesr()函数,猜测是用于保持登陆状态的:
在这里插入图片描述
接着定位该函数,在check.admin.php文件里找到该定义该函数的代码:
在这里插入图片描述
在这里插入图片描述
分析其中的关键代码:

$_SESSION[$this->keepUserIDTag] = $this->userID; 
$_SESSION[$this->keepgroupidTag] = $this->groupid; 
$_SESSION[$this->keepUserNameTag] = $this->userName;

看到生成session的代码以后,既可以选择分析其规律,也可以选择一个取巧的办法,这个方法基于这样一个特点,就是session与cookie不同,不太会变化,基本上同一个cms,这个session能登陆,换一个cms,同样的session也能登陆成功。
因此可以在login.php文件中,将session的值输出,并中止程序的运行。用当前账号密码登陆网站后台,看到:
在这里插入图片描述
这就是session的值了,避免了繁琐的分析session规律的过程。
cookie和session是绑定的,只要session正确,就可以避免登陆的过程直接登陆后台。
对于不同的账户密码的session能否登陆成功,核心得看程序校验了些什么。这里的session并不在乎你的账户名和密码,因此我们可以用自己的session去登陆别人的账号。
得到了session以后,还不能马上用于登陆,需要先满足三个条件:

1、目标文件使用session_start()函数;
2、开启了session_start()的文件需要包含我们可以自定义变量的文件,也就是common.php;
3、session_start()函数一定要在包含的文件之前生效才能使用自己创建session。

先保存好用于传参的session:

_SESSION[duomi_ckstr]=dfwb&_SESSION[duomi_ckstr_last]=&_SESSION[duomi_admin_id]=1&_SESSION[duomi_admin_name]=admin&_SESSION[duomi_group_id]=1

注意:
这里的变量不需要加符号,因为传参进去以后会被自动处理为变量,自动加上这个$符号。接下来就是寻找包含了common.php和使用了session_start()的文件。经过查找发现interface里的好几个文件都符合条件:
在这里插入图片描述
在这里插入图片描述
可以考虑用interface/comment.php文件来传参,传参的过程通过URL地址栏直接传递即可。构造URL如下:

http://192.168.181.128/duomicms/upload/interface/comment.php?_SESSION[duomi_ckstr]=dfwb&_SESSION[duomi_ckstr_last]=&_SESSION[duomi_admin_id]=1&_SESSION[duomi_admin_name]=admin&_SESSION[duomi_group_id]=1

直接访问以后得到如下页面:
在这里插入图片描述
这是怎么回事呢?难道传参失败了吗?访问一下后台地址看看:

http://192.168.181.128/duomicms/upload/admin

在这里插入图片描述
成功进入后台。

四、小结

本文对该通用漏洞的复现过程大体上可以分下以下几个步骤:
1、代码审计,找到传参和设置变量点;
2、发现后台没有过滤session;
3、原则上需要去分析session到底是什么值,分析后确定了session的值再去设置session,这里直接走了捷径;
4、传参并进入后台。

限于本人的时间精力,未能详细展开叙述的地方,还请读者见谅,同时也算是给读者留下一些思考的空间,只有多思考、多动手,才能切实提高自己的水平。

猜你喜欢

转载自blog.csdn.net/weixin_64551911/article/details/125773015
今日推荐