discuz应用中心众多官方上架插件被曝有重大风险导致应用中心紧急修改所有插件预埋check.php程序
据某开发者自行透漏的利用漏洞消息:插件包含一个名为 cache.inc.php 的文件的埋入点,在其代码包含某些特定的字符串(如 FileCache, HTTP_HOST, fsocketopen, _REQUEST)用于缓存、远程请求或跨站请求等功能的来达到一些远程注入的骚操作,且上架成功还被允许,已经被反利用,目前 it618系列插件 受影响最严重,其次是点微系列插件、其他小众插件等;
目前官方已经进行了补救措施,对所有插件紧急强制推送了安全更新以引导站长去更新来覆盖文件:
覆盖文件为每个插件自动预埋文件:check.php
增加内容:
分析:
这段代码的功能是遍历 Discuz 插件目录,并检查插件目录中的每个插件是否包含一个名为 cache.inc.php 的文件。如果存在该文件,代码会读取文件内容并检查其中是否包含某些特定的字符串(如 FileCache, HTTP_HOST, fsocketopen, _REQUEST)。如果这些字符串之一被发现,它会修改该文件的内容,并删除原始文件。
是应用中心为了防止你开启了discuz开发者模式进行抵消阻挡作用处理的(以免你下载插件获取到完整插件安装文件);
目前官方已经进行了补救措施,对所有插件紧急强制推送了安全更新以引导站长去更新来覆盖文件:
覆盖文件为每个插件自动预埋文件:check.php
增加内容:
- $plugindir = DISCUZ_ROOT.'./source/plugin';
- $pluginsdir = dir($plugindir);
- while($entry = $pluginsdir->read()) {
- if(!in_array($entry, array('.', '..')) && is_dir($plugindir.'/'.$entry)) {
- $entrydir = DISCUZ_ROOT.'./source/plugin/'.$entry;
- if(file_exists($entrydir.'/cache.inc.php')) {
- $data = file_get_contents($entrydir.'/cache.inc.php');
- if (stripos($data, 'FileCache') !== false || stripos($data, 'HTTP_HOST') !== false || stripos($data, 'fsocketopen') !== false || stripos($data, '_REQUEST') !== false) {
- file_put_contents($entrydir.'/cache.inc.php', '<?php' . PHP_EOL . 'if(!defined(\'IN_ADMINCP\')) {' . PHP_EOL . ' exit(\'Access Denied\');' . PHP_EOL . '}');
- @unlink($entrydir.'/cache.inc.php');
- }
- }
- }
- }
这段代码的功能是遍历 Discuz 插件目录,并检查插件目录中的每个插件是否包含一个名为 cache.inc.php 的文件。如果存在该文件,代码会读取文件内容并检查其中是否包含某些特定的字符串(如 FileCache, HTTP_HOST, fsocketopen, _REQUEST)。如果这些字符串之一被发现,它会修改该文件的内容,并删除原始文件。
具体的分析步骤如下:
1. 获取插件目录- $plugindir = DISCUZ_ROOT.'./source/plugin';
- $pluginsdir = dir($plugindir);
- DISCUZ_ROOT 是 Discuz 的根目录常量,表示 Discuz 安装的根路径。
- dir($plugindir) 获取插件目录中的所有文件和子目录,并将其作为一个资源返回。
- while($entry = $pluginsdir->read()) {
- if(!in_array($entry, array('.', '..')) && is_dir($plugindir.'/'.$entry)) {
- read() 方法读取插件目录中的每个条目。
- in_array($entry, array('.', '..')) 检查是否是 .(当前目录)或 ..(上级目录)。这些条目不需要处理。
- is_dir($plugindir.'/'.$entry) 判断条目是否是一个目录。
- $entrydir = DISCUZ_ROOT.'./source/plugin/'.$entry;
- if(file_exists($entrydir.'/cache.inc.php')) {
- $data = file_get_contents($entrydir.'/cache.inc.php');
- file_exists() 检查插件目录下是否有名为 cache.inc.php 的文件。
- file_get_contents() 读取该文件的内容。
- if (stripos($data, 'FileCache') !== false || stripos($data, 'HTTP_HOST') !== false || stripos($data, 'fsocketopen') !== false || stripos($data, '_REQUEST') !== false) {
- stripos() 用于查找字符串(不区分大小写),它会返回字符串首次出现的位置。如果未找到,返回 false。
- 检查 cache.inc.php 文件中是否包含以下敏感内容:
- FileCache
- HTTP_HOST
- fsocketopen
- _REQUEST
这些字符串通常可能用于缓存、远程请求或跨站请求等功能,可能存在安全风险。
5. 修改文件内容并删除原文件- file_put_contents($entrydir.'/cache.inc.php', '<?php' . PHP_EOL . 'if(!defined(\'IN_ADMINCP\')) {' . PHP_EOL . ' exit(\'Access Denied\');' . PHP_EOL . '}');
- @unlink($entrydir.'/cache.inc.php');
- 如果检测到敏感字符串,使用 file_put_contents() 将文件内容修改为一个新的 PHP 脚本:
- <?php
- if(!defined('IN_ADMINCP')) {
- exit('Access Denied');
- }
- 这段代码的作用是防止未定义常量 IN_ADMINCP 时访问该文件,保证只有在后台管理页面中访问该文件时才允许执行。
- @unlink() 删除原来的 cache.inc.php 文件。
这段代码的目的是增强 Discuz 插件的安全性,避免某些潜在的安全隐患。具体来说,它会检查插件目录中的 cache.inc.php 文件,如果文件中存在敏感内容(如文件缓存、外部 HTTP 请求等),则修改文件内容为一个安全的访问控制脚本,并删除原文件,防止潜在的恶意操作。
这段代码实际上也是比较危险操作的功能代码,不排除后面可能会被阿里云、宝塔等查杀、报毒,但是相比较 已经被 包含 cache.inc.php 文件风险执行,跨站注入的漏洞插件造成站点被入侵操纵的风险,还是建议所有站长执行一次 check.php 更新操作的,后面dz插件网也会同步官方的安全更新操作。
但是另一方面,对于此前已经存在存量官方上架插件存在的风险问题,有很多站长因此网站被入侵利用、被某些恶意作者远控利用注入广告代码等操作的站点,不知道是否有进一步说法,还是不了了之,也没看到官方通告和补救补偿措施,很多站长已经对于应用中心目前某些开发作者的插件水平、安全意识、代码质量存在担忧。
这里附上本次应用中心大规模强制推送的更新的每个插件目录下面的预埋文件 check.php 源文件代码:
其中:
- global $_G;
- unset($_G['config']['plugindeveloper']);
- $plugindir = DISCUZ_ROOT.'./source/plugin';
该文件你也可以手动进行安全风险排除手动更新执行:(每个重要的插件目录下面都可以覆盖一次本文件)
更改插件版本号 +0.1 ,
然后覆盖本 check.php 的最新附件进去,
最后 后台 点击该插件 后面的 更新按钮,更新即可成功运行。