【漏洞分析】DeDeCMS v5.7 SP2 正式版前台任意用户密码修改漏洞
一、 漏洞概述
1.简介
织梦内容管理系统(DedeCms)以简单、实用、开源而闻名,是国内最知名的 PHP 开源网站管理系统,也是使用用户最多的 PHP 类 CMS 系统,在经历多年的发展,目前的版本无论在功能,还是在易用性方面,都有了长足的发展和进步,DedeCms 免费版的主要目标用户锁定在个人站长,功能更专注于个人网站或中小型门户的构建,当然也不乏有企业用户和学校等在使用该系统。
2018 年 1 月 10 日,锦行信息安全公众号公开了一个关于DeDeCMS前台任意用户密码修改漏洞的细节。
2018 年 1 月 10 日,Seebug 漏洞平台收录该漏洞,漏洞编号为SSV-97074,知道创宇 404 漏洞应急团队成功复现该漏洞。
2. 漏洞限制
只影响前台账户
只能修改未设置安全问题的账户
3. 影响版本
DeDeCMSV5.7SP2 正式版(2018-01-09)
二、 漏洞分析
1. 产生原因
**类型转换问题:**类型转换是无法避免的问题。例如需要将GET或者是POST的参数转换为int类型,或者是两个变量不匹配的时候,PHP会自动地进行变量转换。但是PHP是一个弱类型的语言,导致在进行类型转换的时候会存在很多意想不到的问题。
2. 过程分析
该漏洞便是由于php的自动类型转换导致的,具体位置在member/resetpassword.php的第84行:
从这段判断的开始看起:
77行取* i d ∗ 中的数字部分作为 ∗ id*中的数字部分作为* id∗中的数字部分作为∗mid*;
78行构建取数据库*#@__member*表中mid列值为$mid对应的safequestion,safeanswer,userid和email列的指令;
79行将刚刚得到的 s q l 指令执行的结果赋值给 sql指令执行的结果赋值给 sql指令执行的结果赋值给row;
80、83行分别判断 s a f e q u e s t i o n 、 safequestion、 safequestion、safeanswer的值是否为空字符串,若是则将其赋值为’';
此处便是利用该漏洞的关键:
已知帐号默认的 r o w [ ′ s a f e q u e s t i o n ′ ] 是 ′ 0 ′ (字符串), row['safequestion']是'0'(字符串), row[′safequestion′]是′0′(字符串),_GET[‘safequestion ’]传过来的值为字符串,并且在php中:
<?php
echo empty("0"); // true
echo empty("0.0"); // false
echo '0'=="0.0" // true
?>
要满足传入的$safequestion参数能通过80、84行的判断,可以利用以下url:
http://127.0.0.1/dedecms/member/resetpassword.php?dopost=safequestion&safequestion=0.0&safeanswer=&id=4
将传入的$safequestion值设为"0.0",便可以通过80、84行的判断;
至于$safeanswer本身就为空,所以不用理,id则是你想要修改的账号的mid。
84行将刚刚经过判断的 s a f e q u e s t i o n 、 safequestion、 safequestion、safeanswer和从数据库中取到的 r o w [ ′ s a f e q u e s t i o n ′ ] 、 row['safequestion']、 row[′safequestion′]、row[‘safeanswer’]进行比较是否相等,若都满足则进入sn()函数,并且传入的$send参数为’N’:
可见sn()函数仅是用作限制10分钟内重复发送验证码,由于是第一次请求发送,所以在161行进入newmail()函数,并且传入的$type参数为’INSERT’:
根据$type的值从第86行进入if判断:
88行出现关键变量 k e y 和 key和 key和randval, k e y 是保存在数据库中的临时密码, key是保存在数据库中的临时密码, key是保存在数据库中的临时密码,randval则是修改密码时需要的临时验证码,用于和内部的$key进行比较来实现身份验证;
从77行跟进random()函数得知$randval是一个8位的随机字符串:
然后 r a n d v a l 经过 m d 5 ( ) 函数加密得到 randval经过md5()函数加密得到 randval经过md5()函数加密得到key;
之前传过来的$send参数值为’N’,故跳到96行;
在98行的ShowMsg()中包含““&key=”. r a n d v a l ”,所以可知 randval”,所以可知 randval”,所以可知randval的值包含在将要跳转的url中(可使用bp抓包获得);
而根据要跳转的url:
$cfg_basehost.$cfg_memberurl."/resetpassword.php?dopost=getpasswd&id=".$mid."&key=".$randval
由于该url中直接将$key以GET的方式传入,故125-128行的判断可以通过,所以直接访问抓包获得的url便可以修改密码。
三、 漏洞影响
通过 ZoomEye 网络空间探测引擎进行探测,以下为网络空间上所有的使用了 DeDeCMS 的网站,总数超过100万条:
四、 相关链接
[1] DeDeCMS 官网
http://www.dedecms.com/
[2] 漏洞详情原文
https://mp.weixin.qq.com/s/2ULQj2risPKzskX32WRMeg
[3] Seebug 漏洞平台
https://www.seebug.org/vuldb/ssvid-97074