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