DiscuzX系列命令執行分析公開(三連彈)
0x00 漏洞概要
昨天360補天發了這樣的一條微博:
然後打聽了一下細節,發現居然是我13年7月報給TSRC的漏洞,看今天大家玩的挺開心,與TSRC的人聊了兩句,說這個系列可以發幾個了,所以我也來湊個熱鬧,把原來的分析發出來給大家看一下(這裡做個廣告,TSRC提交Discuz的漏洞,獎品棒棒噠~~)。這個漏洞原來我是作為前臺命令執行發個TSRC的,雖然有限制,但是個人感覺還是不錯的。只發一個怕各位不過癮,就再來一發這個點比較直觀的後臺命令執行和繞過前臺命令執行的修復。原TSRC上的漏洞標題是《Discuz! X系列遠端命令執行漏洞(二)》、《Discuz! X系列遠端命令執行漏洞(三)》和《Discuz! X系列遠端命令執行漏洞(四)》。
下面是原漏洞報告的概要部分:
“騰訊旗下Discuz! X系列cms存在遠端命令執行漏洞,經測試在其2013年6月20日釋出的最新版本的Discuz! X3中仍存在此問題。目前這個漏洞尚未在網路中流傳,屬於0day漏洞。 這個漏洞存在於圖片裁剪功能中,需要管理員啟用ImageMagick上傳圖片功能方可觸發。此漏洞只需一個可訪問論壇內容的賬號,即可利用。”
0x01 原理分析
0. 一定條件下前臺命令執行
這個漏洞出現在\source\class\class_image.php檔案中的Thumb_IM()函式,問題程式碼如下:
#!php
function Thumb_IM() {
switch($this->param['thumbtype']) {
case 'fixnone':
case 1:
if($this->imginfo['width'] > $this->param['thumbwidth'] || $this->imginfo['height'] > $this->param['thumbheight']) {
$exec_str = $this->param['imageimpath'].'/convert -quality '.intval($this->param['thumbquality']).' -geometry '.$this->param['thumbwidth'].'x'.$this->param['thumbheight'].' '.$this->source.' '.$this->target;
$return = exec($exec_str);
if(!file_exists($this->target)) {
return -3;
}
}
break;
//省略部分程式碼
從第一行紅色程式碼中可以看出,程式透過一些變數的拼接形成一條系統命令,在第二行使用exec方法進行執行。若使用者可以控制這些變數中的任何一個,那麼就可能導致任意命令的執行。
1. 同點後臺命令執行
這個漏洞出現在\source\class\class_image.php檔案中的Thumb_IM()函式,問題程式碼如下:
#!php
function Thumb_IM() {
switch($this->param['thumbtype']) {
case 'fixnone':
case 1:
if($this->imginfo['width'] > $this->param['thumbwidth'] || $this->imginfo['height'] > $this->param['thumbheight']) {
$exec_str = $this->param['imageimpath'].'/convert -quality '.intval($this->param['thumbquality']).' -geometry '.$this->param['thumbwidth'].'x'.$this->param['thumbheight'].' '.$this->source.' '.$this->target;
$return = exec($exec_str);
if(!file_exists($this->target)) {
return -3;
}
}
break;
//省略部分程式碼
從第一行紅色程式碼中可以看出,程式透過一些變數的拼接形成一條系統命令,在第二行使用exec方法進行執行。若使用者可以控制這些變數中的任何一個,那麼就可能導致任意命令的執行。
[email protected]! X系列遠端命令執行漏洞分析(二)》報告中提到過這個問題,也已經提交給騰訊修復了,使用的利用點是param['thumbwidth']和param[' thumbheight']。而這次我使用到param['imageimpath']這個引數,這個引數對應的是後臺配置中的“ImageMagick程式安裝路徑”。
這個利用點應該是最後一個可控點了,因為param['thumbwidth']和param[' thumbheight']在提交給騰訊後新增了整形校驗轉換,無法傳遞字串。而source和target需要在前面進行檔案和檔案是否存在的驗證,無法自由發揮☹。
下面來看一下傳遞param['imageimpath']這個引數的程式碼,它的位置在\source\admincp\admincp_checktools.php檔案中:
#!php
$settingnew = $_GET['settingnew'];
if(!empty($_GET['previewthumb'])) {
$_G['setting']['imagelib'] = $settingnew['imagelib'];
$_G['setting']['imageimpath'] = $settingnew['imageimpath'];
$_G['setting']['thumbwidth'] = $settingnew['thumbwidth'];
$_G['setting']['thumbheight'] = $settingnew['thumbheight'];
$_G['setting']['thumbquality'] = $settingnew['thumbquality'];
require_once libfile('class/image');
@unlink(DISCUZ_ROOT.$_G['setting']['attachdir'].'./temp/watermark_temp1.jpg');
@unlink(DISCUZ_ROOT.$_G['setting']['attachdir'].'./temp/watermark_temp2.jpg');
$image = new image;
//省略部分程式碼
可以從紅色程式碼出看到imageimpath引數沒有進行任何過濾,便傳入到全域性變數中了。在後面的image類中使用它也是直接從全域性變數中提取,沒有做任何的過濾和校驗,下面是image類的建構函式程式碼:
#!php
function image() {
global $_G;
$this->param = array(
'imagelib' => $_G['setting']['imagelib'],
'imageimpath' => $_G['setting']['imageimpath'],
'thumbquality' => $_G['setting']['thumbquality'],
'watermarkstatus' => dunserialize($_G['setting']['watermarkstatus']),
'watermarkminwidth' => dunserialize($_G['setting']['watermarkminwidth']),
'watermarkminheight' => dunserialize($_G['setting']['watermarkminheight']),
'watermarktype' => $_G['setting']['watermarktype'],
'watermarktext' => $_G['setting']['watermarktext'],
'watermarktrans' => dunserialize($_G['setting']['watermarktrans']),
'watermarkquality' => dunserialize($_G['setting']['watermarkquality']),
);
}
2. 前臺命令執行修復繞過
[email protected]! X系列遠端命令執行漏洞分析(二)[email protected]! X系列遠端命令執行漏洞分析(三)》兩篇報告中,將視角盯死在了Thumb_IM這個方法上。在修復後,這個方法的命令執行失敗,導致利用後續操作停止。
但是如果讓這個方法正常完成它的工作,那麼他後面的操作中還是有很多修復中沒有考慮到的利用點。下面我們來看下其中的一個利用點,source/class/class_image.php中的Cropper_IM方法:
#!php
function Cropper_IM() {
$exec_str = $this->param['imageimpath'].'/convert -quality 100 '.
'-crop '.$this->param['srcwidth'].'x'.$this->param['srcheight'].'+'.$this->param['srcx'].'+'.$this->param['srcy'].' '.
'-geometry '.$this->param['dstwidth'].'x'.$this->param['dstheight'].' '.$this->source.' '.$this->target;
exec($exec_str);
if(!file_exists($this->target)) {
return -3;
}
}
從上面程式碼可以看出,這個方法先拼接命令,然後透過exec函式執行。在拼接的過程中很多變數的內容是可控的,而且在到達這個方法之前沒有做足夠的校驗和過濾。從而導致攻擊者可以透過傳遞一些帶有命令操作的內容,來達到命令執行的目的。
0x02 利用思路
0. 一定條件下前臺命令執行
看到這個漏洞點後,我就開始嘗試透過關鍵字從原始碼中尋找呼叫Thumb_IM函式的地方。搜尋到使用此函式的檔案很多,但是由於這個函式的前兩個引數都是和上傳檔案的檔名相關,而且discuz對於上傳檔名做了隨機化命名和字尾白名單處理,所以導致前三個引數為不可控點。
所以這之後我將目標點瞄準到圖片寬度和高度這幾個點,從中篩選引數未被寫死的可控呼叫。這樣我找到了\source\module\misc\misc_imgcropper.php檔案,之後大量的時間花費在對於這個檔案呼叫的業務邏輯的查詢上。
1. 一定條件下前臺命令執行
無
2. 前臺命令執行修復繞過
漏洞的觸發點在source/module/misc/misc_imgcropper.php中,部分程式碼如下:
#!php
$cropfile = md5($_GET['cutimg']).'.jpg';
$ictype = $_GET['ictype'];
if($ictype == 'block') {
require_once libfile('function/block');
$block = C::t('common_block')->fetch($_GET['bid']);
$cropfile = block_thumbpath($block, array('picflag' => intval($_GET['picflag']), 'pic' => $_GET['cutimg']));
$cutwidth = $block['picwidth'];
$cutheight = $block['picheight'];
} else {
$cutwidth = $_GET['cutwidth'];
$cutheight = $_GET['cutheight'];
}
$top = intval($_GET['cuttop'] < 0 ? 0 : $_GET['cuttop']);
$left = intval($_GET['cutleft'] < 0 ? 0 : $_GET['cutleft']);
$picwidth = $cutwidth > $_GET['picwidth'] ? $cutwidth : $_GET['picwidth'];
$picheight = $cutheight > $_GET['picheight'] ? $cutheight : $_GET['picheight'];
require_once libfile('class/image');
$image = new image();
$prefix = $_GET['picflag'] == 2 ? $_G['setting']['ftp']['attachurl'] : $_G['setting']['attachurl'];
if(!$image->Thumb($prefix.$_GET['cutimg'], $cropfile, $picwidth, $picheight)) {
showmessage('imagepreview_errorcode_'.$image->errorcode, null, null, array('showdialog' => true, 'closetime' => true));
}
$image->Cropper($image->target, $cropfile, $cutwidth, $cutheight, $left, $top);
showmessage('do_success', dreferer(), array('icurl' => $cropfile), array('showdialog' => true, 'closetime' => true));
}
可以看到在最後呼叫了$image物件的Cropper方法,而這個過程中$cutwidth和$cutheight都是使用者可控的變數,並且在執行到Cropper方法前沒有進行過任何校驗和過濾。
0x03 技術驗證
0. 一定條件下前臺命令執行
在管理員開啟ImageMagick上傳圖片功能的前提下,攻擊者只需要一個普通使用者許可權即可,後臺設定方法如下圖:
由於這個功能是對圖片進行處理的,所以,要在訪問時提供一個本站有效的圖片地址。而且最好是存放在data/attachment目錄下的,因為預設就是這個目錄,否則就要用“../”來修改路徑。
所以我的訪問路徑為:
http://localhost/Discuz_X3.0/upload/misc.php?mod=imgcropper&img=group/19/group_36_banner.jpg
然後使用chrome審查元素功能,修改picwidth的value為“||whoami&”,如下圖所示:
然後點選網頁右下角的裁剪按鈕就觸發了。為了能直觀顯示,我新增了一行程式碼將接受執行結果的$return變數,echo出來並exit來結束掉後面的語句,效果如下圖所示:
1. 同點後臺命令執行
在後臺全域性->上傳設定->ImageMagick 程式安裝路徑
由於這個功能是對圖片進行處理的,所以,要在訪問時提供一個本站有效的圖片地址。而且最好是存放在data/attachment目錄下的,因為預設就是這個目錄,否則就要用“../”來修改路徑。
所以我的訪問路徑為
http://192.168.188.142/DiscuzX3.1_1122/upload/misc.php?mod=imgcropper&img=forum/201312/05/094746ub04zw03jr4wi44m.jpg
然後直接點選左下角的裁剪,雖然會返回圖片訪問錯誤,但是命令卻正常執行了,如下圖所示:
2. ImageMagick
這個漏洞需要在後臺開啟ImageMagick功能,並確保ImageMagick功能正常執行。下圖是我在後臺中開啟的這個功能,並填寫ImageMagick安裝目錄。
如果這個功能開啟,我們甚至可以在沒有賬號的情況下,前臺完成命令執行的觸發。
首先訪問裁切圖片的這個功能,因為這個漏洞的觸發必須要有一張有效圖片,所以我們可以在論壇帖子中隨便找到一張圖片來引用。例如:我的發帖圖片是:
http://192.168.188.143/discuz20140604/data/attachment/forum/201406/13/155944d557e0dtcdpouoad.jpg
那麼我要訪問的裁切功能的URL為:
http://192.168.188.143/discuz20140604/misc.php?mod=imgcropper&img=forum/201406/13/155944d557e0dtcdpouoad.jpg
然後修改POST資料包中cutheight或者cutwidth中的內容為“%26%26mkdir tsrc||”提交,就可以在discuz根目錄下建立一個tsrc的目錄。
修改輸入包如下圖所示:
提交後效果如下圖所示:
相關文章
- discuzX3登入流程分析2017-11-08
- 多執行緒系列(三):執行緒池基礎2018-03-28執行緒
- 開始-執行-命令大全2007-07-23
- Saltstack系列2:Saltstack遠端執行命令2019-10-19
- Hadoop系列,執行jar檔案命令2020-09-30HadoopJAR
- 通過ICMP協議反彈SHELL並執行命令2018-05-23協議
- unittest系列(三)unittest用例如何執行2021-03-14
- 開始-執行命令的大全2010-04-06
- shell指令碼linux命令連續執行2018-06-29指令碼Linux
- 用 Explain 命令分析 MySQL 的 SQL 執行2020-06-15AIMySql
- ctfshow--紅包題第二彈 臨時檔案命令執行2024-04-05
- 三、wss連線B站彈幕2018-09-30
- 深入理解javascript系列(三):執行上下文2018-06-12JavaScript
- Abp框架之執行Update-Database 命令系列錯誤2018-10-24框架Database
- SSH連線伺服器後執行多條命令2021-04-04伺服器
- Discuz! X系列遠端程式碼執行漏洞分析2020-08-19
- 開始→執行→命令集錦(轉)2007-08-10
- 開始-執行-命令大全1182007-09-06
- 實現Xshell斷開連線情況下Linux命令繼續執行2017-06-30Linux
- 【Vulfocus解題系列】手把手教你使用Vulfocus公開靶場對Apache Log4j2遠端命令執行漏洞復現2021-12-12Apache
- netty原始碼分析之揭開reactor執行緒的面紗(三)2018-10-25Netty原始碼React執行緒
- 【線上公開課】Kubernetes實戰系列三??原理篇2020-04-04
- 命令執行漏洞2020-10-20
- Docker執行命令2024-07-28Docker
- 執行wget命令,出錯:無法建立 SSL 連線。2021-03-18wget
- Zookeeper原始碼分析(三) ----- 單機模式(standalone)執行2018-05-10原始碼模式
- Firefox 31~34遠端命令執行漏洞的分析2020-08-19Firefox
- TortoiseSVN 命令 (命令列執行工具)2011-12-30命令列
- 銀彈谷:中國協同辦公行業研究2023-02-13行業
- Mac OS上執行openssl命令操作,生成RSA私鑰和RSA公鑰2016-07-13Mac
- 三類遠端連線命令2020-09-24
- Docker命令-docker exec-在執行的容器中執行命令2020-07-27Docker
- win10系統執行命令在哪裡,win10電腦開啟執行命令的方法2017-06-11Win10
- 多執行緒系列之 執行緒安全2019-01-09執行緒
- Java執行cmd命令2022-02-14Java
- 遠端執行命令2016-09-06
- 命令列執行Nunit2013-10-14命令列
- .net執行cmd命令2024-10-09