代码分析
漏洞利用点主要是php弱类型的判断缺陷,漏洞代码位于 member\resetpassword.php
主要代码如下
1 | else if($dopost == "safequestion") |
1 | if($row['safequestion'] == $safequestion && $row['safeanswer'] == $safeanswer) |
在该处使用了双等号进行判断,因此我们可以利用弱类型的特性进行绕过,默认注册用户是没有设置安全问题的,我们在数据库看一下默认的值
safequestion的值为0,safeanswer值为空
对于上方的判断
1 | if(empty($safequestion)) $safequestion = ''; |
最后的safequestion值为0,safeanswer值为空,这样对于safequestion,我们可以使用0.0 0.这样的字符串使他们强制转换为int后变为0 达到绕过判断的目的,而对于safeanswer我们直接置空就好
绕过之后我们会进入sn()函数
1 | sn($mid, $row['userid'], $row['email'], 'N'); |
定位函数,该函数在/member/inc/inc_pwd_functions.php中,代码如下
1 | function sn($mid,$userid,$mailto, $send = 'Y') |
首先该函数会在#@__pwd_tmp表中查询是否存在临时密码,当我们第一次重置密码时,该表中是没有值的,而后通过下面的判断,我们自然的进入了newmail函数
1 | newmail($mid,$userid,$mailto,'INSERT',$send); |
该函数同样在/member/inc/inc_pwd_functions.php 中,代码如下
1 | function newmail($mid, $userid, $mailto, $type, $send) |
根据前面的参数传递,最后会执行到这里
1 | return ShowMsg('稍后跳转到修改页', $cfg_basehost.$cfg_memberurl."/resetpassword.php?dopost=getpasswd&id=".$mid."&key=".$randval); |
在这里$randval是我们所不知道的随机字符串,但是该行信息会进行回显输出,这也正是我们进行下一步密码重置操作所需要的链接
我们继续来看getpasswd的操作,代码位于 member\resetpassword.php,关键代码如下
1 | else if($dopost == "getpasswd") |
第一次会执行到这里
1 | if(empty($setp)) |
该段代码最后请求了/templets/resetpassword2.htm 这个页面,我们来看一下
页面将step的值修改为2后又回到上面那段代码,接着执行该段
1 | elseif($setp == 2) |
该段进行了最后一步重置密码的操作
漏洞利用
抓包repeater取回带有key的链接
访问该链接,即可重置密码