標籤:失效 初始化 頁面 art http username step mem sms
驗證。參考漏洞:http://wooyun.jozxing.cc/static/bugs/wooyun-2015-0152291.html
漏洞出現在/phpcms/modules/member/index.php 第1687-1756行
public_forget_password_username()函數
public function public_forget_password_username() {$step = intval($_POST[‘step‘]);$step = max($step,1);$this->_session_start();if(isset($_POST[‘dosubmit‘]) && $step==2) {//處理提交申請,以手機號為準if ($_SESSION[‘code‘] != strtolower($_POST[‘code‘])) {showmessage(L(‘code_error‘), HTTP_REFERER);}$username = safe_replace($_POST[‘username‘]);$r = $this->db->get_one(array(‘username‘=>$username),‘userid,email‘);if($r[‘email‘]==‘‘) {$_SESSION[‘userid‘] = ‘‘;$_SESSION[‘code‘] = ‘‘;showmessage("該帳號沒有綁定手機號碼,請選擇其他方式找回!");} else {$_SESSION[‘userid‘] = $r[‘userid‘];$_SESSION[‘email‘] = $r[‘email‘];}$email_arr = explode(‘@‘,$r[‘email‘]);include template(‘member‘, ‘forget_password_username‘);} elseif(isset($_POST[‘dosubmit‘]) && $step==3) {$sms_report_db = pc_base::load_model(‘sms_report_model‘);$mobile_verify = $_POST[‘mobile_verify‘];$email = $_SESSION[‘email‘];if($email){if(!preg_match(‘/^([a-z0-9_]+)@([a-z0-9_]+).([a-z]{2,6})$/‘,$email)) exit(‘check email error‘);if($_SESSION[‘emc_times‘]==‘‘ || $_SESSION[‘emc_times‘]<=0){showmessage("驗證次數超過5次,驗證碼失效,請重新擷取郵箱驗證碼!",HTTP_REFERER,3000);}$_SESSION[‘emc_times‘] = $_SESSION[‘emc_times‘]-1;if($_SESSION[‘emc‘]!=‘‘ && $_POST[‘email_verify‘]==$_SESSION[‘emc‘]) {$userid = $_SESSION[‘userid‘];$updateinfo = array();$password = random(8,"23456789abcdefghkmnrstwxy");$encrypt = random(6,"23456789abcdefghkmnrstwxyABCDEFGHKMNRSTWXY");$updateinfo[‘encrypt‘] = $encrypt;$updateinfo[‘password‘] = password($password, $encrypt);$this->db->update($updateinfo, array(‘userid‘=>$userid));$rs = $this->db->get_one(array(‘userid‘=>$userid),‘phpssouid‘);if(pc_base::load_config(‘system‘, ‘phpsso‘)) {//初始化phpsso$this->_init_phpsso();$this->client->ps_member_edit(‘‘, ‘‘, ‘‘, $password, $rs[‘phpssouid‘], $encrypt);}$_SESSION[‘email‘] = ‘‘;$_SESSION[‘userid‘] = ‘‘;$_SESSION[‘emc‘] = ‘‘;$_SESSION[‘code‘] = ‘‘;pc_base::load_sys_func(‘mail‘);sendmail($email, ‘密碼重設通知‘, "您在".date(‘Y-m-d H:i:s‘)."通過密碼找回功能,重設了本站密碼。");include template(‘member‘, ‘forget_password_username‘);exit;} else {showmessage("驗證碼錯誤!請重新擷取!",HTTP_REFERER,3000);}} else {showmessage("非法請求!");}} else { include template(‘member‘, ‘forget_password_username‘);}}
經曆了第一步:
$step = intval($_POST[‘step‘]);
$step = max($step,1);
$this->_session_start();
這時候開啟_session_start(),然後從phpcms_session取session的值,
然後在第二步時,驗證下賬戶有沒有綁定郵箱。然後就返回這個頁面。點擊擷取郵箱校正碼。
這時候的url是這樣的。
/index.php?m=member&c=index&a=public_get_email_verify&session_code=ftrz&random=0.08188270693514244
執行public_get_email_verify()函數。
public function public_get_email_verify() { pc_base::load_sys_func(‘mail‘); $this->_session_start(); $code = $_SESSION[‘emc‘] = random(8,"23456789abcdefghkmnrstwxy"); $_SESSION[‘emc_times‘]=5; $message = ‘您的驗證碼為:‘.$code; sendmail($_SESSION[‘email‘], ‘郵箱找回密碼驗證‘, $message); echo ‘1‘; }}
然後隨機產生$_SESSION[‘emc‘]的值,利用sendmail發送郵件,發完以後走第三步,驗證校正碼。
這時候的session中存在$_SESSION[‘emc‘]的值,也就是發送到郵件中的值。對於session,只要瀏覽器不關,session值就會一直存在本地,除非到期了。
然後我們退回到第一步,輸入要重設的另一個帳號,這時候的$_SESSION[‘emc‘]值是第一個賬戶的。
然後不走點擊擷取驗證碼,直接來到
elseif(isset($_POST[‘dosubmit‘]) && $step==3) {
輸入第一個賬戶的$_SESSION[‘emc‘]值,然後進行第三步校正,
if($_SESSION[‘emc‘]!=‘‘ && $_POST[‘email_verify‘]==$_SESSION[‘emc‘])
這時候的瀏覽器中的$_SESSION[‘emc‘]值我們是知道的,所以也能進入這個if,然後重設第二個賬戶的密碼。
這個漏洞在phpcmsv9.6.0 中修複了,修複方案就是在第一步查詢$username是否有綁定郵箱的時候加入兩句話,清空$_SESSION[‘emc‘]的值,確保在重設當前賬戶的時候,session中的userid,email是使用者所指定的。
PHPCMS v9.5.8-設計缺陷可重設前台任意使用者密碼