代碼審計-DedeCMS-V5.7前臺任意用戶密碼重置
0x01 漏洞影響
該漏洞允許攻擊者修改任意前臺用戶密碼。
0x02 漏洞利用條件
1,開啟會員模塊
2,攻擊者擁有一個正常的會員賬號
3,目標沒有設置安全問題
0x03 漏洞分析
漏洞文件:/member/resetpassword.php:
這個文件是來找回用戶密碼的,這裏可以通過郵箱找回,也可以通過安全問題找回。
來看看代碼中問題出在哪裏:
這裏先接受了一個id變量,用來查詢用戶。
接下來看到
這裏的dpost變量就是找回用戶密碼的操作,可以通過郵件找回也可以通過安全問題找回,上圖就是通過安全問題找回($dopost == "safequestion")
首先mid變量通過正則來過濾提交的id參數,然後拼接到下面的select查詢語句中,
$sql = "SELECT safequestion,safeanswer,userid,email FROM #@__member WHERE mid = ‘$mid‘";
這些都是先找到需要找回密碼的用戶的信息。
漏洞重點在這裏:
if(empty($safequestion)) $safequestion = ‘‘; if(empty($safeanswer)) $safeanswer = ‘‘;
判斷這兩個變量是否為空,是就等於空字符,這兩個變量對應的就是找回密碼的安全問題和安全問題的答案
接下來判斷,我們在找回密碼頁面提交的安全問題和答案是否和數據庫中存的一樣,一樣的話進入執行這個sn函數,這個就是找回密碼的,否則不是
問題就出在從數據庫中獲取safequestion,然後與傳過來的數據進行判等。用的是雙等號,又因為用戶沒有設置安全問題,數據庫裏面默認存的是0。
通過php弱類型的轉換‘0.0‘ == ‘0‘了。(內部運算:先是把0.0(浮點數(0.0)轉換為int(0),然後字符串(‘0‘)轉換為int(0),最後 0==0 ,所以相等了。)
可以看到使用”0.0”,”0.”,”0e1”都可以繞過前面的判斷,最後進入sn()函數,繼續跟進。
(記住這裏我們的send默認為N)
sn()函數在文件/member/inc/inc_pwd_functions.php:
這裏發現還是要進行發郵箱驗證,繼續跟進newmail函數,看看是否可以不用驗證郵箱進行繞過。
elseif($send == ‘N‘) { return ShowMsg(‘稍後跳轉到修改頁‘, $cfg_basehost.$cfg_memberurl."/resetpassword.php?dopost=getpasswd&id=".$mid."&key=".$randval); }
可以看到當send為N時,直接在前端頁面返回了驗證碼。(而我們這裏剛好默認就是N,見前文)
又因為用戶id是我們可以控制的,safequestion(默認情況)下可以繞過。
那麽也就達成了修改前臺任意用戶密碼的效果。
0x04 漏洞驗證
通過分析代碼我們知道我們請求的地址是這樣了
http://192.168.5.149/DedeCMS-V5.7/uploads/member/resetpassword.php?dopost=safequestion&safequestion=0.0&id={userid}
這裏我們註冊兩個個賬號:
賬號一 test 密碼test 這是我們的目標賬號 id為2
賬號二 secquan 密碼 secquan 這是我們的攻擊賬號 id為3
這裏登錄了secquan的賬號 ,我們要重置目標id為2的賬號,發送請求url,
http://192.168.5.149/DedeCMS-V5.7/uploads/member/resetpassword.php?dopost=safequestion&safequestion=0.0&id=2
這裏直接返回了郵箱驗證裏的驗證碼
這時候我們再來請求修改頁URL:
http://192.168.5.149/DedeCMS-V5.7/uploads/member/resetpassword.php?dopost=getpasswd&id=2&key=ROivopAb
然後就可以直接重置密碼了。
這裏修改id的值即可修改對應的用戶的密碼。
但是這個漏洞存在一個缺陷,因為通過分析可以看出來只有沒有設置安全問題的用戶才會受此漏洞的影響;而且只能修改前臺用戶的密碼。
代碼審計-DedeCMS-V5.7前臺任意用戶密碼重置