### 简要描述: 验证过于简单啊。 ### 详细说明: 在source/member.php中 ``` function retrieve_password(){ if($this->syArgs("go")){ if($GLOBALS['G_DY']['vercode']==1){ if(!$this->syArgs("vercode",1)||md5(strtolower($this->syArgs("vercode",1)))!=$_SESSION['doyo_verify'])message("验证码错误"); } $ok=false; $user=$this->syArgs("user",1); $email=$this->syArgs("email",1); if($email){ if($user){ $conditions = array('user' => $user,'email' => $email); $m = syDB('member')->find($conditions,null,'id,user,email'); if(!$m){message("没有找到匹配的用户和邮箱,请确认用户名及邮箱输入正确。");}else{$ok=true;} }else{ $conditions = array('email' => $email); $num = syDB('member')->findCount($conditions); if($num<1)message("没有找到匹配的用户和邮箱,请确认用户名及邮箱输入正确。"); if($num>1)message("此邮箱注册了多个账号,必须填写用户名才可找回密码。"); if($num==1){$m = syDB('member')->find($conditions,null,'id,user,email');$ok=true;} } }else{ message("请输入email地址"); } if($ok){ $http=get_domain(); $subject=$http.'密码找回邮件'; $token=md5($this->syArgs("vercode",1).$email.time());...
### 简要描述: 验证过于简单啊。 ### 详细说明: 在source/member.php中 ``` function retrieve_password(){ if($this->syArgs("go")){ if($GLOBALS['G_DY']['vercode']==1){ if(!$this->syArgs("vercode",1)||md5(strtolower($this->syArgs("vercode",1)))!=$_SESSION['doyo_verify'])message("验证码错误"); } $ok=false; $user=$this->syArgs("user",1); $email=$this->syArgs("email",1); if($email){ if($user){ $conditions = array('user' => $user,'email' => $email); $m = syDB('member')->find($conditions,null,'id,user,email'); if(!$m){message("没有找到匹配的用户和邮箱,请确认用户名及邮箱输入正确。");}else{$ok=true;} }else{ $conditions = array('email' => $email); $num = syDB('member')->findCount($conditions); if($num<1)message("没有找到匹配的用户和邮箱,请确认用户名及邮箱输入正确。"); if($num>1)message("此邮箱注册了多个账号,必须填写用户名才可找回密码。"); if($num==1){$m = syDB('member')->find($conditions,null,'id,user,email');$ok=true;} } }else{ message("请输入email地址"); } if($ok){ $http=get_domain(); $subject=$http.'密码找回邮件'; $token=md5($this->syArgs("vercode",1).$email.time()); $url=$GLOBALS['WWW'].'index.php?c=member&a=reset_password&id='.$m['id'].'&token='.$token; $body='您在'.$GLOBALS['S']['title'].'提交了密码找回邮件,点击下面的链接进行密码重置:<a href="'.$http.$url.'" target="_blank">【点击此处进行密码重置】</a>,如果本次找回密码不是您亲自操作,请忽略本邮件。'; $send=syClass('syphpmailer'); $retrieve=$send->Send($email,$m['user'],$subject,$body); if(!$retrieve){ message('邮件发送失败,请联系管理员。'); }else{ syDB('member')->update(array('id'=>$m['id']),array('token'=>$token,'tokentime'=>time())); message('密码已成功发送至您的邮箱,请点击邮件内容中的链接设置新密码,有效期3天。','?c=member'); } } } ``` 在这里 修改密码主要就是用$token 可是$token的验证太弱了。 ``` $token=md5($this->syArgs("vercode",1).$email.time()); ``` 看token的由来, 是用找回密码的时候的验证码 和 邮箱 和 时间戳。 所以我们知道要改用户的邮箱就可以直接修改他的密码。 ### 漏洞证明: [<img src="https://images.seebug.org/upload/201404/131201253973beb50f18bd723bfb6429c6fd988d.jpg" alt="do4.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201404/131201253973beb50f18bd723bfb6429c6fd988d.jpg) 首先把验证码记录上 eqkm 这里用户名不需要填。 然后记录时间戳。1397361568 [<img src="https://images.seebug.org/upload/201404/1312022070fa563ccac618c43b776405d30990a8.jpg" alt="do5.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201404/1312022070fa563ccac618c43b776405d30990a8.jpg) 然后 对 eqkmxiaoyu@qq.com1397361568 md5一次 得到adc044125e0a5e96d37f2a171c8b3d96 则token就为这个。 但是对方的id我们是不知道的。 这不要紧。 载入burpsuite直接跑一次就行了。 token我们已经知道了。 就只需要其他用户的id了。 这里把id设置为变量 然后穷举。 [<img src="https://images.seebug.org/upload/201404/131206287452b59d29863952c5f975c929d89544.jpg" alt="do6.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201404/131206287452b59d29863952c5f975c929d89544.jpg) 观察length 就知道当16的时候是正确的 则用户的id为16. 然后直接访问。 [<img src="https://images.seebug.org/upload/201404/131207565beac693568bbaff359f11817ee19ec5.jpg" alt="do7.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201404/131207565beac693568bbaff359f11817ee19ec5.jpg) 即可直接修改其他用户的密码。