PHPCMS v9.5.8-設計缺陷可重置前臺任意用戶密碼
驗證。參考漏洞: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([email protected]
經歷了第一步:
$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-設計缺陷可重置前臺任意用戶密碼