简介
Discuz!ML是一个由CodersClub.org创建的多语言,集成,功能齐全的开源网络平台,用于构建像“社交网络”这样的互联网社区。
二次修改
看了下大佬和alpha实验室的大佬写的文章之后,我自愧不如,还有挺多细节没写清楚,决定改改,按照大佬的思路再修改自己的文章,添加其中忽略的细节。
代码浅析
查看代码,跟踪DISCUZ_ROOT
,根据上面代码引入,require './source/class/class_core.php';
require DISCUZ_ROOT.'./source/function/function_home.php';
require DISCUZ_ROOT.'./source/function/function_portal.php';
所以,我们跟进的是class_core.php
里面的DISCUZ_ROOT
DISCUZ_ROOT
是当前目录,引入当前目录的/source/function/function_home.php /source/function/function_portal.php
控制mod 在可引用文件范围之内
if(empty($_GET['mod']) || !in_array($_GET['mod'], array('list', 'view',
'comment', 'portalcp', 'topic', 'attachment', 'rss', 'block')))
$_GET['mod'] = 'index';
来到最后一行,require_once
引用通过libfile
函数对路径拼接并检查后的文件
这里拼接过后是protal_index.php
,所以我们再去分析protal_index.php
在protal_index.php
中,引用了template
动态修改模板。
刚开始程序会读取相应的模板,然后通过正则表达式替换修改模板,并且写文件
在function_core的tample
函数里,跟踪DISCUZ_LANG
这个常量值
在discuz_application.php
中,发现DISCUZ_LANG
是由$lng
这个变量定义的,然后在这个文件中搜索$lng
搜索到$lng
的起源,原来是通过cookie
赋值的,并且,cookie
中的lng
没有过滤,所以可控点在cookie
的language
中。
再回来,看看拼接的地方
$cachefile = './data/template/'.DISCUZ_LANG.'_'.(defined('STYLEID') ? STYLEID.'_' : '_').$templateid.'_'.str_replace('/', '_', $file).'.tpl.php';
生成的缓存文件,互相引用,include template()
生成其他的缓存文件
在sc'.system('dir').'__common_header_portal_index.tpl.php
中的第3、4、5行,发现构造的恶意代码system('dir')
被执行。
总结
在复现这个代码漏洞时,一直想不懂他这个命令是怎么被解析的,找了半天才找到解析的地方(太菜了orz
复现的过程中,再代入,如果是我审计这个代码的时候,我会怎么入手,跟踪DISCUZ_ROOT、DISCUZ_LANG
虽然有点马后炮,但是代码审计跟踪变量也是正常的思路
上面解析代码的地方应该是没有把缓存文件创建成功的。
最后,最重要的是,漏洞点应该是include temlate
这个地方,因为template
函数里拼接字符串的变量没有做想过的过滤。
修复建议
个人觉得对$lng
变量做相关过滤就行了,这里就给出过于详细的代码(专注力渐渐失去
https://www.anquanke.com/post/id/181887
https://www.4hou.com/vulnerable/19183.html