1

Discuz ML V3.x 代码注入漏洞详细分析

 2 years ago
source link: https://cyc1e183.github.io/2019/07/13/Discuz-ML-V3-x-%E4%BB%A3%E7%A0%81%E6%B3%A8%E5%85%A5%E6%BC%8F%E6%B4%9E%E8%AF%A6%E7%BB%86%E5%88%86%E6%9E%90/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Discuz ML V3.x 代码注入漏洞详细分析

发表于

2019-07-13 更新于 2020-03-04 分类于 Cyc1e的漏洞分析之路

阅读次数: 24
本文字数: 2.7k 阅读时长 ≈ 2 分钟

0x00 前言

7月11号Discuz ML被爆出存在任意代码注入漏洞,Discuz在国内的用户量还是很可观的,国外还没有去关注,从官方下载源码对漏洞的原理详细的分析了一下,源码地址(http://discuz.ml/download)

0x01 POC

GET / HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:56.0) Gecko/20100101 Firefox/56.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://127.0.0.1/CMS/discuz.ml/vot-discuz.ml-fa108dcc726d/upload/install/index.php?method=ext_info&language=sc
Cookie: UM_distinctid=16961881c34a-0be7f060296b93-173b7740-1a9640-16961881c35265; CNZZDATA5770257=cnzz_eid%3D1356317550-1552119465-%26ntime%3D1554215107; ECS[visit_times]=11; CNZZDATA1257137=cnzz_eid%3D591241165-1552785038-%26ntime%3D1552785038; GK9p_2132_saltkey=ek5JjJGL; GK9p_2132_lastvisit=1562973338; GK9p_2132_sid=SW5SHK; GK9p_2132_lastact=1562977009%09forum.php%09; O2FL_2132_saltkey=ao6mCm4C; O2FL_2132_language=sc%27.phpinfo().%27; O2FL_2132_lastvisit=1562973840; O2FL_2132_sid=MVTcHf; O2FL_2132_lastact=1562977475%09index.php%09; O2FL_2132_sendmail=1; O2FL_2132_onlineusernum=1
Connection: keep-alive
Upgrade-Insecure-Requests: 1
Cache-Control: max-age=0
O2FL_2132_language=sc%27.phpinfo().%27;

0x02 漏洞分析

这里分析Discuz ML v3.4源码,该漏洞主要是通过控制缓存文件的内容,之后缓存文件又被系统调用从而触发,根据POC可知是通过构造Cookie中language的值进行代码注入,在language中构造错误代码判断漏洞触发文件。
)都是require()和include()报错,也就是说是包涵的文件出了问题,到forum_index.php中查看一下

这里是调用缓存文件,根据报错信息可以知道导致报错的缓存文件是:data/template/sc’11_common_header_forum_index.tpl.php,很明显文件名中有部分片段是取自language的值,同时也就是说构造的POC会被植入到缓存文件中,跟进到template()中查看缓存文件的生成规则(function_code.php 644行)

很明显,缓存文件的命名规则由多部分组成,其中第一部分区自DISCUZ_LANG,根据前面的报错信息也可以知道,这个变量的值也就是Cookie中language字段的值,该函数最终返回DISCUZ_ROOT.$cachefile,可想而知,最终返回的便是缓存文件路劲用于文件包含,这里追溯一下DISCUZ_LANG(discuz_application.php定义)

DISCUZ_LANG的值取自于变量$lng,变量$lng的值取自于cookie language

很明显language字段的值没有经过任何过滤直接传到了变量$lng的值,直接用该字段对缓存文件进行命名,这也是导致该漏洞触发的直接原因。
接下来分析一下注入的代码是如何植入到缓存文件中的,定位到template类进行分析(class_template.php),在Discuz程序运行过程中,会读取template/default/common/目录下的默认模版

模版读取的内容传入到变量$template中,并对$template进行字符串替换操作

关键点在于变量$header

$headeradd .= "|| checktplrefresh('$tplfile', '$fname', ".time().", '$templateid', '$cachefile', '$tpldir', '$file')\n";

将checktplrefresh也写入到缓存文件中,文件内容类型于

<?php if(!defined('IN_DISCUZ')) exit('Access Denied'); 
0
|| checktplrefresh('./template/default/common/xxx', './template/default/common/xxx', 1562977476, '1', './data/template/[$cachefile]', './template/default', 'common/xxx')
;?>

结合上面的分析,其中变量$cachefile是我们可以控制的,也就是说控制生成的恶意变量名会被当作变量值写入到缓存文件中,别切恰好缓存文件会担子template()函数的返回值直接被包涵调用,这就太完美了,结合一下代码拼接,所以直接在language字段构造任意代码,例如sc'.phpinfo().'(sc也可以不要),查看生成的缓存文件的内容。

由于代码包含的原因,所以注入到缓存文件中的恶意代码直接执行,其中首页就有包涵,全局搜索一下的话,应该有不少地方有进行包含可以直接利用。

0x03 修复建议

缓存缓文件名固定即可,加过滤的话也很容易被绕过。

由于是任意代码注入漏洞,而且漏洞利用方式很简单,而且国内discuz的论坛较多,所以影响会很大。

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK