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);