dedecms5.7修改前台登陆密码漏洞复现
Dedecms5.7修改前台登陆密码漏洞复现
准备工作
1.搭建dedecms5.7
从网上下载dedecms5.7源码,找到了里面uploads文件夹,改名成dedecms5.7
利用phpstudy在win10本地搭建dedecms网站,将dedecms5.7文件夹置于WWW文件夹下
在浏览器输入localhost/dedecms5.7/install/index.php进行安装
一路按默认继续,直到遇到数据库设定页面:
按照你phpstudy的mysql数据库密码修改后,按继续
到这里先进网站后台
利用默认账号密码admin admin登入
然后在系统选项中找到系统基本参数,再选择会员设置,最后将是否开启会员功能选项改成 是。
最后不要忘了点 确定 保存更改,
到此基本的搭建已经完成。
复现过程
先注册一个账号,
随意填写信息,但是注意不要设置安全问题
然后打开url:http://127.0.0.1/dedecms5.7/member/resetpassword.php
输入你想要修改的账号的密码,邮箱随便填写,用burpsuite抓包,:
抓到的包:
将post内容改为:
dopost=safequestion&id=1&userid=test&safequestion=0.0&safeanswer=&&vdcode=6t1w |
为什么这么改?在之后的漏洞分析我会具体解释,在这里只要知道 safequestion是密保问题,safeanswer是密保问题答案,还有id = 1 意思是第一个注册的用户也就是我们刚刚注册的用户 test。
然后重发包,得到:
http://localhost/DedeCMS5.7/member/resetpassword.php?dopost=getpasswd&id=1&key=WeK8N6k0 |
在burpsuite上放包,然后再上面将这个url复制到浏览器打开,发现我们进入了修改密码界面,
修改后,成功登入,
漏洞成因分析
漏洞成因
在用户密码重置模块,存在php弱类型比较,导致了如果用户没有设置密保问题的情况下可以绕过验证密保问题,直接修改密码(管理员账户默认不设置密保问题)。但是这里修改的密码是member表中的密码,即使修改了管理员密码也是member表中的管理员密码,仍是无法进入后台管理页面。
问题代码分析
dedecms的/member/resetpassword.php就是用来处理用户密码重置的问题的代码,问题出在75行开始处理验证密保问题处。
我们可以发现,这段代码主要是从数据库中查询该用户的密保问题和密保答案,然后与用户输入的密保答案比较,但是在比较的时候使用了弱类型比较 **==**。
if($row['safequestion'] == $safequestion && $row['safeanswer'] == $safeanswer) |
我们查看empty函数可以知道,”0”(字符串0)被认为是空的,但是“0.0”(字符串0.0)不被认为为空,
查询数据库用户数据可以知道,我们设置的test用户,safequestion从数据库取出默认为’0’(没有设置密保),safeanswer为空。
结合上面分析的empty函数特性,如果我们输入 safequestion=‘0’ 会被判断为空,即会进入if内重新将$safequestion赋值为’’。而’从数据取出来的$row[safequestion]为’0’, 而’0’ != ‘’,这样就会打印”对不起,您的安全问题或答案回答错误”,故我们需要输入一个不会被empty判为空,且弱类型等于’0’的字符串。’00’、’000’、’0.0’以上这些都是可以的。因此我们要构造这样的POST数据:
dopost=safequestion&id=1&userid=test&safequestion=0.0&safeanswer=&&vdcode=6t1w |
这样我们就会调用sn函数,这里注意成功调用sn的函数里将 $send设置成了’N’:
sn($mid, $row['userid'], $row['email'], 'N'); |
接着查看sn函数源码,它在member/inc/inc_pwd_functions.php的155行,
再跟踪newmail,它与sn在同一个php里,
在newmail,我们分析代码可以知道,在sn函数中将 $send设置成了’N,其实就是生成了暂时密码并插入了数据库中,并跳转到修改密码页面
else if ($send == 'N') |
这里打印出来的跳转链接就是修改密码页面的链接了,有了它我们就能修改该用户的密码了。