Discuz! X 3.4 ML 任意程式碼執行漏洞復現
- 2019 年 10 月 6 日
- 筆記
0X1 漏洞概述
2019年7月11日,網路上出現了一個Discuz!ML遠程程式碼執行漏洞的PoC,研究員驗證分析發現,攻擊者能夠利用該漏洞在請求流量的cookie欄位中(language參數)插入任意程式碼,執行任意程式碼,從而實現完全遠程接管整個伺服器的目的,該漏洞利用方式簡單,危害性較大。漏洞影響範圍包括如下版本。
Discuz! ML v.3.4、Discuz! ML v.3.3、Discuz! ML v.3.2 源碼下載鏈接:https://bitbucket.org/vot/discuz.ml/downloads/
0X2 漏洞分析
根據公告定位文件source/module/portal/portal_index.php第32行

查看問題函數上方查看定義函數以及關聯文件的位置,可以看到template函數在/source/function/function_core.php中,繼續跟進

問題程式碼如下所示。
$cachefile = './data/template/'.DISCUZ_LANG.'_'.(defined('STYLEID') ? STYLEID.'_' : '_').$templateid.'_'.str_replace('/', '_', $file).'.tpl.php';
程式將快取文件寫在了/data/template/目錄下,文件名由DISCUZ_LANG等多個變數組成,問題就出在這兒了,看看DISCUZ_LANG的值是哪兒獲取來的:

可以看到從程式全部變數$_G['config']['output']['language']中獲取了該值。繼續跟進看看該值可以定位到/source/class/discuz/discuz_application.php:

在304行,系統通過Cookie獲取了語言的值,並在341行定義了前面要找的DISCUZ_LANG,值為Cookie中獲取到的$lng。可以看到整個過程沒有任何的過濾。整個流程即就是:外部參數`$lng`(即language語言)可控,導致`template` 函數生成的臨時模板文件名可操縱,插入自己的程式碼,最終`include_once`包含一下最終導致了程式碼注入。那這裡可以搜一下其他的可利用點,全局查找:

大約有60多個點可以用的。
0X3 漏洞利用
訪問論壇主頁,在Cookie的language欄位值後面拼接php程式碼:
'.phpinfo().'

執行命令獲得管理員許可權:


0X4 漏洞修復
在/source/class/discuz/discuz_application.php 第338行之後341行之前加入該程式碼暫緩此安全問題:
$lng = str_replace("(","",$lng);$lng = str_replace(")","",$lng);$lng = str_replace_replace('"',"",$lng);$ln("'","",$lng);$lng = strg = str_replace('`',"",$lng);