-
-
[原创][漏洞复现]DedeCMS v5.7 SP2_任意修改前台用户密码
-
发表于: 2022-1-19 13:06 6400
-
dedecms v5.7可以在前台进行任意修改前台用户密码
DedeCMS v5.7 SP2
在/member/resetpasswordd.php,定义了整个密码的充值过程
我们来分析一下
在源码的开头处包含进行了一些配置文件以及功能函数文件,之后接受了一个id变量,用来查询用户
之后检查了dopost是否为空,如果为空则重定向到密码重置,若不空则在这里进行匹配,当dopost为getpwd则对用户输入的验证码、邮箱、用户名进行合法校验
接着往下看
在这里会首先判断找回密码的方式,这里一共提供了两种:
我们仔细看这一行代码
此处的比较是利用"==",弱类型比较
该漏洞的触发点在于以安全问题找回密码时的不安全性逻辑设计所导致的,所以我们根据流程进入到以"安全问题"找回密码的逻辑代码中继续分析,可以看到这里会根据之前传递进来的用户id作为参数从数据库查询对应的safequestion、safeanswer,之后于用户提供的safequestion以及safeanswer进行判断。
如果用户没有设置安全问题,数据库里存储的safequestion默认为"0",safeanswer默认为'null',在此处我们可以利用弱类型转换构造成立,例如
我们可以测试一下
可以看到返回值为true
我们来跟进sn函数
在该函数中会首先进行初始化赋值操作(此处的send为上面传递进来的'N'),之后跟进传递的id进行一次sql查询,之后进行判断,在这里我们直接根据newmail查看发送邮件的函数具体实现
注意这里
可以看到当send为'N'时,直接在前端页面返回了验证码,又因为用户id是我们可以控制的safequestion下可以绕过,那么也就达成了修改前台任意用户密码的攻击
这里我准备了两个账号
攻击者:test\test id=2
被攻击者:test2\1 id=3
第一步:
我们登录到攻击者的账号
第二步:
抓包发送以下请求获取key值
第三步:
利用key去进行重置密码,访问url
可以看到成功跳转到了被攻击者的密码找回,我们将其密码改为hacker
登陆验证一下:
登陆成功,完成了密码修改
1、将if ($row['safequestion'] == $safequestion && $row['safeanswer'] == $safeanswer)
中的"=="更换"==="
2、及时升级系统到最新版本
<?php
require_once(dirname(__FILE__).
"/config.php"
);
require_once(DEDEMEMBER.
"/inc/inc_pwd_functions.php"
);
if
(empty($dopost)) $dopost
=
"";
$
id
=
isset($
id
)? intval($
id
) :
0
;
<?php
require_once(dirname(__FILE__).
"/config.php"
);
require_once(DEDEMEMBER.
"/inc/inc_pwd_functions.php"
);
if
(empty($dopost)) $dopost
=
"";
$
id
=
isset($
id
)? intval($
id
) :
0
;
if
($dopost
=
=
"")
{
include(dirname(__FILE__).
"/templets/resetpassword.htm"
);
}
elseif($dopost
=
=
"getpwd"
)
{
/
/
验证验证码
if
(!isset($vdcode)) $vdcode
=
'';
$svali
=
GetCkVdValue();
if
(strtolower($vdcode) !
=
$svali || $svali
=
=
'')
{
ResetVdValue();
ShowMsg(
"对不起,验证码输入错误!"
,
"-1"
);
exit();
}
/
/
验证邮箱,用户名
if
(empty($mail) && empty($userid))
{
showmsg(
'对不起,请输入用户名或邮箱'
,
'-1'
);
exit;
}
else
if
(!preg_match(
"#(.*)@(.*)\.(.*)#"
, $mail))
{
showmsg(
'对不起,请输入正确的邮箱格式'
,
'-1'
);
exit;
}
else
if
(CheckUserID($userid, '
', false) != '
ok')
{
ShowMsg(
"你输入的用户名 {$userid} 不合法!"
,
"-1"
);
exit();
}
$member
=
member($mail, $userid);
if
($dopost
=
=
"")
{
include(dirname(__FILE__).
"/templets/resetpassword.htm"
);
}
elseif($dopost
=
=
"getpwd"
)
{
/
/
验证验证码
if
(!isset($vdcode)) $vdcode
=
'';
$svali
=
GetCkVdValue();
if
(strtolower($vdcode) !
=
$svali || $svali
=
=
'')
{
ResetVdValue();
ShowMsg(
"对不起,验证码输入错误!"
,
"-1"
);
exit();
}
/
/
验证邮箱,用户名
if
(empty($mail) && empty($userid))
{
showmsg(
'对不起,请输入用户名或邮箱'
,
'-1'
);
exit;
}
else
if
(!preg_match(
"#(.*)@(.*)\.(.*)#"
, $mail))
{
showmsg(
'对不起,请输入正确的邮箱格式'
,
'-1'
);
exit;
}
else
if
(CheckUserID($userid, '
', false) != '
ok')
{
ShowMsg(
"你输入的用户名 {$userid} 不合法!"
,
"-1"
);
exit();
}
$member
=
member($mail, $userid);
/
/
以邮件方式取回密码;
if
($
type
=
=
1
)
{
/
/
判断系统邮件服务是否开启
if
($cfg_sendmail_bysmtp
=
=
"Y"
)
{
sn($member[
'mid'
],$userid,$member[
'email'
]);
}
else
{
showmsg(
'对不起邮件服务暂未开启,请联系管理员'
,
'login.php'
);
exit();
}
/
/
以安全问题取回密码;
}
else
if
($
type
=
=
2
)
{
if
($member[
'safequestion'
]
=
=
0
)
{
showmsg(
'对不起您尚未设置安全密码,请通过邮件方式重设密码'
,
'login.php'
);
exit;
}
require_once(dirname(__FILE__).
"/templets/resetpassword3.htm"
);
}
exit();
}
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();
}
}
/
/
以邮件方式取回密码;
if
($
type
=
=
1
)
{
/
/
判断系统邮件服务是否开启
if
($cfg_sendmail_bysmtp
=
=
"Y"
)
{
sn($member[
'mid'
],$userid,$member[
'email'
]);
}
else
{
showmsg(
'对不起邮件服务暂未开启,请联系管理员'
,
'login.php'
);
exit();
}
/
/
以安全问题取回密码;
}
else
if
($
type
=
=
2
)
{
if
($member[
'safequestion'
]
=
=
0
)
{
showmsg(
'对不起您尚未设置安全密码,请通过邮件方式重设密码'
,
'login.php'
);
exit;
}
require_once(dirname(__FILE__).
"/templets/resetpassword3.htm"
);
}
exit();
}
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();
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
赞赏
- 牧云·主机管理助手测评 6582
- [原创]JAVA安全—反射 813
- [原创]CISCN2022-东北赛区半决赛eztp解题思路 13033
- [XCTF]第四期个人能力认证考核个人wp 9655
- [原创]记录一次对某CMS漏洞挖掘 1449