DedeCMS 前端任意用户密码修改漏洞

Posted by JenI on 2018-01-22 00:00:00+08:00

前言

织梦CMS是集简单、健壮、灵活、开源几大特点的开源内容管理系统,是国内开源CMS的领先品牌,目前程序安装量已达七十万,超过六成的站点正在使用织梦CMS或基于织梦CMS核心开发。最近,织梦CMS最新版被曝存在前端任意用户密码修改漏洞,漏洞分析如下:

漏洞分析

漏洞出现在会员模块的重设密码功能上,也就是 /member/resetpasswordd.php 中:

dedePm1

上面的代码在接收到重设密码请求时,将请求中的 id 值处理后带入数据库进行查询,然后对请求中的 safequestion 和 sefeanswer 字段进行了是否为空的判断,这两个字段为注册账号时填写的安全问题和问题答案,如果用户在注册时没有填写的话,数据库中这两个字段默认为字符串 ’0’。

为了满足 $row['safequestion'] == $safequestion,就需要将 $safequestion 设置为 ’0’,但是如果 $safequestion 为 ‘0’,就会无法满足 empty($safequestion) 的判断,因此这里需要将 $safequestion 设置为 ‘0.0’。PHP 是一个弱类型语音,两个 == 进行判断时,只要两侧值相等就返回真。这里其实是内部做了类型转换,传入的 ‘0.0’ 会首先被 int() 转换为 0,数据库中取出的字符串 ‘0’ 也会转为整型,此时就满足了 $row['safequestion'] == $safequestion。代码执行到 sn 函数,该函数位于 member/inc/inc_pwd_functions.php 文件中:

dedePm2

sn 函数中的 $send 默认值是 Y,但是在上面函数调用处传入了 N。之后进入到 newmail 函数:

dedePm3

newmail 函数随机生成了一个 8 位的临时密码,将其插入到 dede_pwd_tmp 表后确定传入的 send 变量是否为 N,如果为 N,就将跳转提示加上临时随机密码输出到页面上,利用这个临时密码,攻击者就可以更改任意用户的密码了。

漏洞复现

下面是 user2 用户利用此漏洞修改 user1 用户密码的流程。

  • 首先在 DedeCMS 搭建的网站上注册两个用户。默认没有安全提示问题。
    用户一: 用户名:user1,密码:user1password
    用户二: 用户名:user2,密码:user2password
dedePm4

dedePm5

  • 这时使用 user2 账户登录,访问 /member/resetpassword.php?dopost=safequestion&safequestion=0.0&id=8。因为 user1 用户的 mid 为 8,所以这里的 id 设置为 8。
dedePm6

dedePm7

  • 成功得到了临时密码,删除 amp; 转发数据包。
dedePm8

  • 将 user1 用户的密码修改为 00000000。
dedePm9

  • 修改成功后使用用户名 user1、密码 00000000 成功登录。
dedePm10

参考

https://paper.seebug.org/507/


作者:   JenI   转载请注明出处,谢谢


Comments !