DiscuzML 3.x 代码注入
前言
漏洞刚出来时候发现分析文章很少,只能自己审计审计。根据poc,首先要排除是否是文件名导致的代码注入(可能就我在纠结这个吧,太菜了估计)。
带这个疑问了下群里@xq17师傅,在自己进行如下验证。
通过修改缓存内容判断是读内容导致代码注入,还有就是查看文件包含点,是include_once
如果有可执行代码会报出error
直接结束程序。
复现环境
php5.6
deepin
版本Discuz!ML 3.4
漏洞验证
根据poc,将cookie中language字段拼接'.phpinfo().'
可实现代码注入
漏洞触发原因
未过滤cookie输入
漏洞分析
通过debug报错找到文件包含处在文件/upload/source/module/portal/portal_index.php第32行
include_once template('diy:portal/index');
跟进该函数查看返回值为"DISCUZ_ROOT.$cachefile;"
,溯源$cachefile
其中DISCUZ_LANG
值为cookie
中字段language
值可控,导致$cachfile文件名可控
$this->var['oldlanguage'] = $lng; // Store Old Language Value for compare
// define DISCUZ_LANG
define('DISCUZ_LANG', $lng);
$cachefile = './data/template/'.DISCUZ_LANG.'_'.(defined('STYLEID') ? STYLEID.'_' : '_').$templateid.'_'.str_replace('/', '_', $file).'.tpl.php';
跟进模板操作函数checktplrefresh
,跟进parse_template
模板解析函数。文件/upload/source/class/class_template.php第84行将$headeradd拼接进模板中,往回看该文件70-77行。
headeradd字符串拼接为|| checktplrefresh('$tplfile', '$fname', ".time().", '$templateid', '$cachefile', '$tpldir', '$file')\n"
,其中$cachefile
正好是可控,导致文件包含之后拼接的代码执行。
$headeradd = $headerexists ? "hookscriptoutput('$basefile');" : '';
if(!empty($this->subtemplates)) {
$headeradd .= "\n0\n";
foreach($this->subtemplates as $fname) {
$headeradd .= "|| checktplrefresh('$tplfile', '$fname', ".time().", '$templateid', '$cachefile', '$tpldir', '$file')\n";
}
$headeradd .= ';';
}
可触发的代码的文件只有en’.phpinfo().’11_common_header_portal_index.tpl.php
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!