源码下载地址:http://discuz.ml/download
0x01 简析
通过渠道已知是cookie -> language这里出现的问题,可直接加个/符构造报错,至于为什么呢?往下看漏洞成因就能理解了

在 PHP Debug 信息中从上至下跟一下

跟入 forum_index.php 可以看到是包含临时文件,暂时没有具体的内容,跟进 template
include template('diy:forum/discuz:'.$gid);
下面是关键几行代码
function template($file, $templateid = 0, $tpldir = '', $gettplfile = 0, $primaltpl='') {
...
/*vot*/ $cachefile = './data/template/'.DISCUZ_LANG.'_'.(defined('STYLEID') ? STYLEID.'_' : '_').$templateid.'_'.str_replace('/', '_', $file).'.tpl.php';
...
checktplrefresh($tplfile, $tplfile, @filemtime(DISCUZ_ROOT.$cachefile), $templateid, $cachefile, $tpldir, $file);
return DISCUZ_ROOT.$cachefile;
}
在$cachefile参数值中,通过阅读代码可以明确只有DISCUZ_LANG是非直接从上层传递过来的,并在checktplrefresh()中判断如果模板缓存文件不存在,或者缓存文件的更改时间小于模板文件的更改时间,则生成新的缓存文件

那么假如能控制DISCUZ_LANG,等于能控制一部分文件名
跟入定义,DISCUZ_LANG 值来源于 $lng
define('DISCUZ_LANG', $lng);
注意到,$lng可以来源于两个地方,$_GET以及$_COOKIE,但是对GET会有检查导致无法利用,而对cookie则是完全信任没有过滤

那么现在通过设置cookie -> language就可以控制文件名了,那么如何控制文件内容呢?
回到开始,由于include存在,我们控制的点实际是类似这样的
include('test'.phpinfo().'');
所以实际为代码注入,执行效果类似如下

0x02 利用
目标页面只要使用
include template()即可
修改
cookie->xxxx_language值满足以下格式即可
0x03 效果
