Discuz!所有版本,版本转换功能导致Getshell[截至X3.4 R20191201]
1、简述存在问题的代码在/utility/convert/目录下,这部分的功能主要是用于Dz系列产品升级/转换。影响范围:全版本条件:存在/utility/convert/目录和相应功能。2、复现环境同上,目前gitee最新版代码依然存在该漏洞。3、漏洞复现在产品升级/转换->选择产品转换程序 ->设置服务器信息 这里抓包,payload:POST /dz/utility/convert/index.php HTTP/1.1Host: 127.0.0.1:8001
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:74.0) Gecko/20100101 Firefox/74.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;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
Content-Type: application/x-www-form-urlencoded
Content-Length: 278
Origin: http://127.0.0.1:8001
Connection: close
Referer: http://127.0.0.1:8001/dz/utility/convert/index.php
Upgrade-Insecure-Requests: 1
a=config&source=d7.2_x1.5&submit=yes&newconfig=aaaa4、漏洞分析入口utility/convert/index.phprequire './include/common.inc.php';
$action = getgpc('a');
$action = empty($action) ? getgpc('action') : $action;
$source = getgpc('source') ? getgpc('source') : getgpc('s');取$_POST['a'],直接赋值给$action,此时$action = config;} elseif($action == 'config' || CONFIG_EMPTY) {
require DISCUZ_ROOT.'./include/do_config.inc.php';
} elseif($action == 'setting') {满足条件,引入./include/do_config.inc.php@touch($configfile);
......
if(submitcheck()) {
$newconfig = getgpc('newconfig');
if(is_array($newconfig)) {
$checkarray = $setting['config']['ucenter'] ? array('source', 'target', 'ucenter') : array('source', 'target');
foreach ($checkarray as $key) {
......
}
save_config_file($configfile, $newconfig, $config_default);$newconfig从$_POST获取数据,save_config_file函数保将$newconfig保存到$configfile文件中,即config.inc.php文件。跟进该函数。function save_config_file($filename, $config, $default) {
$config = setdefault($config, $default);// 将$config中的空白项用 $default 中对应项的值填充
$date = gmdate("Y-m-d H:i:s", time() + 3600 * 8);
$year = date('Y');
$content = <<<EOT
<?php
\$_config = array();
EOT;
$content .= getvars(array('_config' => $config));
$content .= "\r\n// ".str_pad('THE END', 50, '-', STR_PAD_BOTH)." //\r\n\r\n?>";
file_put_contents($filename, $content);
}getvars函数处理,此时的$config = $newconfig+config.default.php对应项的补充。看一下getvars函数:function getvars($data, $type = 'VAR') {
$evaluate = '';
foreach($data as $key => $val) {
if(!preg_match("/^*$/", $key)) {
continue;
}
if(is_array($val)) {
$evaluate .= buildarray($val, 0, "\${$key}")."\r\n";
} else {
$val = addcslashes($val, '\'\\');
$evaluate .= $type == 'VAR' ? "\$key = '$val';\n" : "define('".strtoupper($key)."', '$val');\n";
}
}
return $evaluate;
}满足if条件会执行buildarray函数,此时$key=_config,$val=上面的$config。最终造成写入的在该函数中(update.php 2206行):foreach ($array as $key => $val) {
if($level == 0) {
//str_pad — 使用另一个字符串填充字符串为指定长度
// 第一个参数是要输出的字符串,指定长度为50,用'-'填充,居中
$newline = str_pad('CONFIG '.strtoupper($key).'', 50, '-', STR_PAD_BOTH);
$return .= "\r\n// $newline //\r\n";
}本意是使用$config数组的key作为每一块配置区域的"注释标题",写入配置文件的$newline依赖于$key,而$key是攻击者可控的。未对输入数据进行正确的边界处理,导致可以插入换行符,逃离注释的作用范围,从而使输入数据转化为可执行代码。5、修复建议update.php 2206行foreach ($array as $key => $val){
//过滤掉$key中的非字母、数字及下划线字符
根据你提供的漏洞描述,这是一个典型的文件写入漏洞,攻击者可以通过构造特定的POST请求,将恶意代码写入到`config.inc.php`文件中,从而导致Getshell。以下是漏洞的详细分析和修复建议:
### 漏洞分析:
1. **漏洞入口**:`utility/convert/index.php` 文件中的代码逻辑存在问题。`$action` 和 `$newconfig` 直接从 `$_POST` 中获取,没有进行严格的过滤和验证。
2. **漏洞触发点**:
- 当 `$action` 的值为 `config` 时,程序会引入 `./include/do_config.inc.php` 文件。
- 在 `do_config.inc.php` 中,`$newconfig` 从 `$_POST` 中获取数据,并通过 `save_config_file` 函数将其保存到 `config.inc.php` 文件中。
- 由于 `$newconfig` 没有经过严格的过滤,攻击者可以通过构造恶意数据,将任意代码写入 `config.inc.php` 文件中,从而实现Getshell。
3. **漏洞利用**:
- 攻击者可以通过构造特定的POST请求,将恶意代码写入 `config.inc.php` 文件中。
- 例如,攻击者可以提交一个包含PHP代码的 `newconfig` 参数,该代码将被写入 `config.inc.php` 文件中,从而在服务器上执行任意代码。
### 修复建议:
1. **输入过滤**:
- 对 `$newconfig` 进行严格的过滤和验证,确保其内容符合预期格式,避免恶意代码的注入。
- 可以使用 `htmlspecialchars`、`addslashes` 等函数对输入数据进行转义,或者使用正则表达式进行格式验证。
2. **文件写入权限控制**:
- 确保 `config.inc.php` 文件的写入权限受到严格控制,避免攻击者通过漏洞写入恶意代码。
- 可以在写入文件之前,检查文件内容是否包含恶意代码,或者限制文件写入的权限。
3. **代码重构**:
- 建议对 `utility/convert/index.php` 和 `./include/do_config.inc.php` 文件进行重构,增加对输入数据的严格验证和过滤。
- 例如,可以在 `save_config_file` 函数中增加对 `$newconfig` 的检查,确保其内容不包含恶意代码。
4. **安全补丁**:
- 建议及时更新Discuz!到最新版本,官方可能已经发布了相关的安全补丁。
- 如果官方尚未发布补丁,可以手动修改相关代码,增加安全防护措施。
### 示例修复代码:
// 在 save_config_file 函数中增加对 $newconfig 的检查
function save_config_file($filename, $config, $default) {
$config = setdefault($config, $default);
// 检查 $config 是否包含恶意代码
if (preg_match('/<\?php/i', serialize($config))) {
die('Invalid config data');
}
$date = gmdate("Y-m-d H:i:s", time() + 3600 * 8);
$year = date('Y');
$content = "<?php\n\n";
$content .= "// $filename\n";
$content .= "// Created: $date\n";
$content .= "// Discuz! (C) 2001-$year Comsenz Inc.\n\n";
foreach ($config as $key => $value) {
$content .= "\$config['$key'] = " . var_export($value, true) . ";\n";
}
$content .= "\n?>";
if (!file_put_contents($filename, $content)) {
die('Unable to write config file');
}
}
### 总结:
该漏洞的核心问题在于未对用户输入进行严格的过滤和验证,导致攻击者可以通过构造恶意请求将代码写入配置文件。通过增加输入过滤、文件写入权限控制以及代码重构等措施,可以有效修复该漏洞,提升系统的安全性。
如果你有更多关于Discuz!的问题,欢迎继续提问!
-- 本回答由 人工智能 AI智能体 生成,内容仅供参考,请仔细甄别。 这个问题涉及到Discuz!的版本转换功能中的一个安全漏洞,可能导致Getshell(即攻击者通过漏洞获取服务器的控制权限)。以下是详细的分析和解决方案:
### 漏洞分析
1. **漏洞位置**:漏洞存在于`/utility/convert/index.php`文件中,特别是在处理`config`操作时。
2. **漏洞触发条件**:当用户通过POST请求提交`a=config`时,程序会直接引入`./include/do_config.inc.php`文件,并在其中处理用户提交的`newconfig`参数。
3. **漏洞利用**:攻击者可以通过构造恶意的`newconfig`参数,将恶意代码写入`config.inc.php`文件中,从而在服务器上执行任意代码。
### 漏洞复现
1. **环境准备**:搭建一个Discuz!环境,并确保`/utility/convert/`目录存在。
2. **漏洞触发**:通过POST请求提交恶意数据,如:
POST /dz/utility/convert/index.php HTTP/1.1
Host: 127.0.0.1:8001
Content-Type: application/x-www-form-urlencoded
Content-Length: 278
a=config&source=d7.2_x1.5&submit=yes&newconfig=恶意代码
3. **结果**:恶意代码被写入`config.inc.php`文件,攻击者可以通过访问该文件执行任意代码。
### 解决方案
1. **删除或禁用`/utility/convert/`目录**:如果不需要使用版本转换功能,可以直接删除或重命名该目录,防止攻击者利用该漏洞。
2. **限制访问权限**:确保只有管理员可以访问`/utility/convert/`目录,可以通过服务器配置(如Nginx或Apache)来限制访问。
3. **输入验证和过滤**:在`do_config.inc.php`文件中,增加对`newconfig`参数的严格验证和过滤,确保只有合法的配置数据才能被写入配置文件。
4. **更新到最新版本**:检查是否有官方发布的补丁或更新,及时更新到最新版本以修复已知漏洞。
### 代码修复示例
在`do_config.inc.php`文件中,增加对`newconfig`参数的验证:
if(submitcheck()) {
$newconfig = getgpc('newconfig');
if(is_array($newconfig)) {
// 增加对$newconfig的验证
foreach ($newconfig as $key => $value) {
if (!preg_match('/^+$/', $key)) {
die('Invalid config key');
}
if (!is_scalar($value)) {
die('Invalid config value');
}
}
$checkarray = $setting ? array('source', 'target', 'ucenter') : array('source', 'target');
foreach ($checkarray as $key) {
// 继续处理
}
}
save_config_file($configfile, $newconfig, $config_default);
}
### 总结
该漏洞的根源在于未对用户输入进行严格的验证和过滤,导致攻击者可以通过构造恶意请求在服务器上执行任意代码。通过删除或禁用相关目录、限制访问权限、增加输入验证和过滤等措施,可以有效防止该漏洞的利用。同时,建议定期检查并更新Discuz!到最新版本,以确保系统的安全性。
如果你有更多关于Discuz!的问题,欢迎随时提问!
-- 本回答由 人工智能 AI智能体 生成,内容仅供参考,请仔细甄别。
页:
[1]