Discuz!ML V3.X 代码注入复现与原理分析

poc

1
2
3
4
5
6
7
8
9
10
GET /Discuz/upload/forum.php HTTP/1.1
Host: 169.254.183.180
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) Gecko/20100101 Firefox/68.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: close
Cookie: lpAo_2132_saltkey=gJ6FRwO6; lpAo_2132_language=en'.phpinfo().'; lpAo_2132_lastvisit=1563156484; lpAo_2132_sid=G5YO6z; lpAo_2132_lastact=1563160086%09home.php%09misc; lpAo_2132_onlineusernum=1; lpAo_2132_sendmail=1
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0

漏洞描述

Discuz 系列建站软件(以下简称DZ)是目前国内部署最为广泛的建站系统,经过多年的发展,已成为集CMS、Forum、Blog等功能为一体的社区系统,并具备完善的插件和模板机制,使得针对DZ进行二次开发变得非常有效率。

由于Discuz!ML V3.X 的cookie字段中language参数未经过过滤,被拼接后直接写入缓存中,随后缓存又被加载导致了任意代码执行。

受影响的系统版本

1
2
3
4
5
Discuz! ML v.3.4

Discuz! ML v.3.3

Discuz! ML v.3.2

漏洞分析

在debug模式下Poc中扔入过长代码执行会报错.根据debug报错信息进行溯源。

以 forum.php 为例,进入模块通常会首先加载内核代码,通过加载 class_core.php 即可,
参考源码:require './source/class/class_core.php';

内核代码加载完成后,接着加载对应模块的代码,包括对应的函数库、相关类库等等;比如 forum 模块就会加载:

参考源码:require './source/function/function_forum.php';

Dz 每个大模块都是有很多子模块构成,访问或者调用这些子模块通常都是通过 URL 传参数来实现,比如:论坛版块(Forum)可以有论坛版块展示或者帖子内容展示等不同的操作,论坛版块展示则通过加载 forumdisplay 模块来实现,参考源码:require DISCUZ_ROOT.'./source/module/forum/forum_'.$mod.'.php';

其中 $mod 的值就是 forumdisplay,而如果当前操作是帖子内容展示,则 $mod 的值为 viewthread。

Discuz 调用实例:1、”http://www.bacysoft.cn/forum.php?mod=viewthread&tid=57“

1
2
3
入口文件:forum.php, /forum.php
模块文件:viewthread,/source/module/forum/forum_viewthread.php
其他参数:tid, 帖子ID号

我们进入forum.php line:76

由于我们并没有加载子模块所以默认$mod为index,forum.php line:49

进入forum_index.php line:432,被污染的php缓存文件就是从这里被加载进来的

其中$cachefile因为未对DISCUZ_LANG变量进行过滤为我们可控变量

全局搜索DISCUZ_LANG,可以发现在discuz_application.php line:341时对其进行定义

可以看到在同文件下discuz_application.php line:305对$lng进行赋值,这里可以清楚看到其中并未对var['cookie']['language']进行任何过滤,这也是该漏洞形成的根本原因

回到function_core.php文件,
进入function_core.php line:653

在经过了一轮的替换

最后在class_template.php line:105中将缓存写入文件,进行包含,这时该缓存文件并没有被我们污染

但在该缓存文件line:1,进行了再次包含

最终包含了包括该缓存文件共五个文件

其中问题出在en'.phpinfo().'_1_1_common_header_forum_index.tpl.php文件

可以看到在class_template.php line:30时,将template\default\common\footer.htm文件对$template变量进行赋值

由于footer.htm中 {subtemplate分别在line:1 line:140 line:200 多次出现,导致在
class_template.phpline line:46 时进行回调函数时候对$this->subtemplates进行赋值

导致对$headeradd进行赋值,由于$cachefile为可控变量,所以$headeradd也为我们可控的

可以看到同样在该文件中,class_template.phpline line:84 将$headeradd变量写入缓存中 这时只要$cachefile里面包含类似'.phpinfo().'就可以将危险的函数嵌入到缓存文件中

最后因为缓存文件被包含导致我们的写入的危险函数被执行导致我们可以做到任意代码执行的效果

参考

Discuz!ML V3.X 代码注入分析

Discuz ML! V3.X 代码注入漏洞深度分析

Discuz 整体架构及内核浅析一:调用流程(For DzX3.2)

Discuz ML! V3.X 代码注入漏洞深度分析

本文标题:Discuz!ML V3.X 代码注入复现与原理分析

文章作者:MuseLJH

发布时间:2019年07月15日 - 16:51

最后更新:2019年07月15日 - 16:59

原始链接:https://museljh.github.io/2019/07/15/Discuz!ML V3.X 代码注入复现与分析/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

-------------END-------------
0%