作者:LoRexxar'@知道創宇404實驗室

0x01 背景

織夢內容管理系統(DedeCms)以簡單、實用、開源而聞名,是國內最知名的PHP開源網站管理系統,也是使用用戶最多的PHP類CMS系統,在經歷多年的發展,目前的版本無論在功能,還是在易用性方面,都有了長足的發展和進步,DedeCms免費版的主要目標用戶鎖定在個人站長,功能更專注于個人網站或中小型門戶的構建,當然也不乏有企業用戶和學校等在使用該系統。

2018年1月10日, 錦行信息安全公眾號公開了一個關于DeDeCMS前臺任意用戶密碼修改漏洞的細節[2]。

2018年1月10日,Seebug漏洞平臺[3]收錄該漏洞,漏洞編號為SSV-97074,知道創宇404漏洞應急團隊成功復現該漏洞。

2018年1月17日,阿里先知平臺公開了一個任意用戶登陸漏洞[4][5],和一個安全隱患[6],通過組合漏洞,導致后臺密碼可以被修改。

2018年1月18日,知道創宇404漏洞應急團隊成功復現該漏洞。

0x02 漏洞簡述

整個漏洞利用鏈包括3個過程:

  1. 前臺任意用戶密碼修改漏洞
  2. 前臺任意用戶登陸漏洞
  3. 前臺管理員密碼修改可影響后臺的安全隱患

通過3個問題連起來,我們可以重置后臺admin密碼,如果我們獲得了后臺地址,就可以進一步登陸后臺進行下一步攻擊。

1、前臺任意用戶密碼修改漏洞

前臺任意用戶密碼修改漏洞的核心問題是由于DeDeCMS對于部分判斷使用錯誤的弱類型判斷,再加上在設置初始值時使用了NULL作為默認填充,導致可以使用弱類型判斷的漏洞來繞過判斷。

漏洞利用有幾個限制:

  1. 漏洞只影響前臺賬戶 admin賬戶在前臺是敏感詞無法登陸
  2. admin賬戶的前后臺密碼不一致,無法修改后臺密碼。
  3. 漏洞只影響未設置密保問題的賬戶
2、前臺任意用戶登陸漏洞

前臺任意用戶登陸漏洞主要是利用了DeDeCMS的機制問題,通過一個特殊的機制,我們可以獲得任意通過后臺加密過的cookie,通過這個cookie我們可以繞過登陸,實現任意用戶登陸。

漏洞利用有一個限制:

如果后臺開啟了賬戶注冊審核,那就必須等待審核通過才能進行下一步利用。

3、前臺管理員密碼修改可影響后臺的安全隱患

在DeDeCMS的設計中,admin被設置為不可從前臺登陸,但是當后臺登陸admin賬戶的時候,前臺同樣會登陸管理員賬戶。

而且在前臺的修改密碼接口,如果提供了舊密碼,admin同樣可以修改密碼,并且這里修改密碼會同步給后臺賬戶。

通過3個漏洞配合,我們可以避開整個漏洞利用下的大部分問題。

前臺任意用戶密碼修改漏洞->修改admin密碼,前臺任意用戶登錄漏洞->登陸admin賬戶,通過剛才修改的admin密碼,來重置admin賬戶密碼。

0x03 漏洞復現

1、 登陸admin前臺賬戶

安裝DeDeCMS

注冊用戶名為000001的賬戶

由于是本地復現漏洞,所以我們直接從數據庫中修改為審核通過

訪問

http://your_website/member/index.php?uid=0000001

獲取cookie中last_vid_ckMd5值,設置DeDeUserID_ckMd5為剛才獲取的值,并設置DedeUserID為0000001

訪問

http://your_website/member/

2、修改admin前臺登陸密碼

使用DeDeCMS前臺任意用戶密碼修改漏洞修改admin前臺密碼。

構造漏洞利用請求

http://yourwebsite/member/resetpassword.php

dopost=safequestion&safequestion=0.0&safeanswer=&id=1

從Burp獲取下一步利用鏈接

/member/resetpassword.php?dopost=getpasswd&id=1&key=nlszc9Kn

直接訪問該鏈接,修改新密碼

成功修改登陸admin密碼

3、修改后臺密碼

訪問

http://yourwebsite/member/edit_baseinfo.php

使用剛才修改的密碼再次修改密碼

成功登陸

0x04 代碼分析

1、 前臺任意用戶登陸

在分析漏洞之前,我們先來看看通過cookie獲取登陸狀態的代碼。

/include/memberlogin.class.php 161行

通過GetCookie函數從DedeUserID取到了明文的M_ID,通過intval轉化之后,直接從數據庫中讀取該id對應的用戶數據。

讓我們來看看GetCookie函數

/include/helpers/cookie.helper.php 56行

這里的cfg_cookie_encode是未知的,DeDeCMS通過這種加鹽的方式,來保證cookie只能是服務端設置的,所以我們沒辦法通過自己設置cookie來登陸其他賬戶。

這里我們需要從別的地方獲取這個加密后的值。

/member/index.php  161行

161行存在一段特殊的代碼,這段代碼是用來更新最新的訪客記錄的,當last_vid沒有設置的時候,會把userid更新到這個變量中,更新到flag中。

而這里的userid就是注冊時的用戶名(如果不是已存在的用戶名的話,會因為用戶不存在無法訪問這個頁面)。

通過這種方式,我們就可以通過已知明文來獲取我們想要的密文。

這里我們通過注冊userid為形似00001或者1aaa這樣的用戶,在獲取登陸狀態時,mid會經過intval的轉化變為1,我們就成功的登陸到admin的賬戶下。

ps:該漏洞影響所有用戶

2、前臺任意用戶密碼修改

漏洞主要邏輯在 /member/resetpassword.php 75行至95行

當找回密碼的方式為安全問題時

dedecms會從數據庫中獲取用戶的安全問題、回答進行比對,當我們在注冊時沒設置安全問題時。

從數據庫中可以看到默認值為NULL(admin默認沒有設置安全問題)

下面是設置了安全問題時數據庫的樣子,safequestion代表問題的id,safeanswer代表安全問題的回答。

我們需要繞過第一個判斷

if(empty($safequestion)) $safequestion = '';

這里我們只要傳入0.0就可以繞過這里,然后0.0 == 0為True,第二個判斷NULL==""為True,成功進入sn函數。

跟入/member/inc/inc_pwd_functions.php 第150行

有效時間10分鐘,進入newmail函數

跟入/member/inc/inc_pwd_functions.php 第73行

77行通過random生成了8位的臨時密碼。

這里我們使用的是安全問題修改密碼,所以直接進入94行,將key代入修改頁。

跳轉進入形似

/member/resetpassword.php?dopost=getpasswd&id=1&key=nlszc9Kn

的鏈接,進入修改密碼流程

唯一存在問題的是,這里&錯誤的經過一次編碼,所以這里我們只能手動從流量中抓到這個鏈接,訪問修改密碼。

3、修改后臺密碼安全隱患

在DeDeCMS的代碼中,專門對前臺修改管理員密碼做了設置,如果是管理員,則一并更新后臺密碼,也就是這個安全隱患導致了這個問題。

/member/edit_baseinfo.php 119行

0x05 修復方案

截至該文章完成時,DeDeCMS的官方仍然沒有修復該漏洞,所以需要采用臨時修復方案,等待官方正式修復更新。

由于攻擊漏洞涉及到3個漏洞,但官方仍然沒有公開補丁,所以只能從一定程度上減小各個漏洞的影響。

  • 前臺任意用戶登陸漏洞:開啟新用戶注冊審核,當發現userid為1xxxx或1時,不予以 通過審核。

在官方更新正式補丁之前,可以嘗試暫時注釋該部分代碼,以避免更大的安全隱患

/member/index.php 161-162行

  • 前臺修改后臺管理員密碼:設置較為復雜的后臺地址,如果后臺地址不可發現,則無法登陸后臺。
  • 前臺任意用戶密碼修改漏洞:

修改文件/member/resetpassword.php 第84行

將其中的==修改為===

即可臨時防護該該漏洞。

0x06 ref

[1] DeDeCMS官網
http://www.dedecms.com/
[2] 漏洞詳情原文
https://mp.weixin.qq.com/s/2ULQj2risPKzskX32WRMeg
[3] Seebug漏洞平臺
https://www.seebug.org/vuldb/ssvid-97074
[4] 阿里先知平臺漏洞分析1
https://xianzhi.aliyun.com/forum/topic/1959
[5] 阿里先知平臺漏洞分析2
https://xianzhi.aliyun.com/forum/topic/1961
[6] 漏洞最早分析原文
http://www.cnblogs.com/iamstudy/articles/dedecms_old_version_method.html


Paper 本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/507/