DedeCMS V5.7 SP2文件上传漏洞深度剖析:从复现到代码加固

news2026/3/13 17:07:02
1. 漏洞背景与环境搭建大家好我是老张一个在安全圈摸爬滚打了十来年的老兵。今天想和大家深入聊聊一个经典的CMS漏洞——DedeCMS V5.7 SP2的前台文件上传漏洞。这个漏洞虽然官方早就出了补丁但它的成因和绕过手法非常典型直到今天很多开发者编写文件上传功能时依然会犯类似的错误。理解它不仅能帮你复现一个历史漏洞更能让你从根本上明白如何写出更安全的代码。咱们不搞那些虚头巴脑的理论直接上手从环境搭建到代码审计最后给出比官方补丁更“硬核”的加固方案。首先我们得把漏洞环境给搭起来。这个漏洞的复现需要几个前提条件你得有一个DedeCMS V5.7 SP2的安装包一个Web服务器环境比如PHPMySQL并且需要管理员权限。我推荐大家直接在本地用PHPStudy或者XAMPP这类集成环境来搭建方便又安全不会影响到线上业务。具体的搭建步骤很简单去官网或开源镜像站下载DedeCMS-V5.7-SP2-UTF8.tar.gz这个版本。注意一定要是SP2版本其他版本可能不存在这个特定问题。解压后将uploads文件夹里的所有文件复制到你的网站根目录比如wwwroot/dedecms。通过浏览器访问这个目录就会自动跳转到安装向导。数据库配置那里填写你本地MySQL的信息就行。这里有个小坑安装过程中有个“体验数据包”的选项千万不要勾选因为体验包可能会引入一些未知的变量影响我们后续对纯净漏洞的分析。安装完成后用设置好的管理员账号登录后台。默认情况下DedeCMS的会员功能是关闭的而这个漏洞的触发恰恰需要开启它。所以我们需要进入后台的“系统” - “系统基本参数” - “会员设置”将“是否开启会员功能”改为“是”。环境就这么跑起来了。接下来才是重头戏。2. 漏洞复现与绕过技巧环境准备好了咱们就来亲手触发一下这个漏洞。这个过程就像侦探破案一步步跟着线索走特别有意思。首先用刚才的管理员账号在前台进行“会员登录”。登录成功后点击进入“会员中心”。你会发现发表文章之前系统会提示你先完善个人信息。这个步骤照做就行填些假数据也能过。然后找到“发表文章”的入口点进去。关键的操作来了在文章编辑器的工具栏里找到一个图片图标点击它上传图片。这时系统会弹出一个文件选择对话框。我们先按规矩来上传一张正常的test.jpg图片。上传成功后编辑器里会显示图片同时在上传窗口的“图像”选项卡里你能看到服务器返回的图片路径比如/uploads/userup/1/xxx.jpg。访问这个路径图片能正常显示而且你会发现图片右下角被自动加上了网站水印。这说明文件确实经过了服务器的图像处理库很可能是GD库的处理这是一个重要的背景信息。现在我们试试直接上传一个PHP webshell文件比如内容为?php eval($_POST[‘cmd’]);?的shell.php。毫无疑问会被系统直接拒绝页面上可能会提示“文件类型不正确”。这是最基础的防御。那么漏洞是怎么被利用的呢核心在于“文件后缀名检测的绕过”。根据漏洞分析问题出在系统对文件名中特殊字符的过滤逻辑上。我们可以制作一个“图片马”来尝试绕过。所谓图片马就是将PHP代码附加到一张真实图片的末尾。这样文件头依然是标准的图片格式如PNG、JPEG但文件内容包含了恶意代码。制作方法在Windows命令行下很简单copy /b normal.png shell.php webshell.png这条命令会将normal.png和shell.php二进制合并生成一个新文件webshell.png。用十六进制编辑器查看这个新文件你会发现文件开头是PNG的文件头末尾则是一段PHP代码。真正的绕过手法直接上传这个webshell.png大概率还是会被拦截因为系统会检查文件内容吗不一定。这里的突破口是在HTTP请求中修改文件名。我们需要使用抓包工具比如Burp Suite。在上传webshell.png时用Burp拦截发出的POST请求。你会看到请求体中有一个字段包含了文件名比如filename”webshell.png”。这时我们将文件名修改为webshell.png.pHp注意大小写变换和点号。为什么这样能成功因为早期很多系统的过滤逻辑是“删除文件名中的某些特殊字符”而不是“严格校验后缀名”。当系统试图过滤掉文件名中的点号.或特殊字符时可能因为逻辑不严谨导致过滤后产生了新的、可被解析的后缀。修改后放行请求如果漏洞存在服务器通常会返回一个包含文件存储路径的响应比如/uploads/userup/1/webshell.png.pHp。激动人心的时刻到了直接访问这个链接。如果返回了空白页或者没有任何图片格式的错误再用中国菜刀或蚁剑等连接工具尝试用http://你的地址/uploads/userup/1/webshell.png.pHp作为URL密码为cmd进行连接。如果成功连接并可以执行命令那么漏洞就复现成功了这证明服务器将.pHp文件当作PHP脚本执行了。3. 源码审计漏洞根源深度剖析复现成功只是看到了现象作为开发者和安全研究员我们必须挖出问题的根子。这就需要我们深入源码进行审计。这个漏洞的根源文件位于/include/dialog/select_images_post.php这是处理图片上传对话框请求的核心文件。让我们打开这个文件聚焦于关键的第36行附近具体行号可能因版本微调而略有差异但逻辑一致$imgfile_name trim(preg_replace(#[ \r\n\t\*\%\\\/\?gt;lt;\|\:]{1,}#, , $imgfile_name));这行代码的本意是进行安全过滤它使用preg_replace函数将文件名中出现的空格、换行符、制表符以及* % \ / ? | :这些特殊字符替换为空字符串即删除。这个正则表达式看起来挺全面但它犯了一个致命的错误它只做了一次过滤并且没有递归或循环处理。我们来模拟一下攻击者的Payload原始文件名为shell.png.pHp。系统首先经过这行代码处理。文件名中的点号.不在这个过滤列表里所以不会被删除。因此shell.png.pHp安然无恙地通过了这行过滤。漏洞的关键在于后续的代码是如何判断文件类型的。通常系统会从$cfg_imgtype配置中获取允许的图片后缀如jpg|gif|png然后用一个正则去匹配文件名。如果代码像这样$cfg_imgtype “jpg|gif|png”; if(!preg_match(“#\.(“.$cfg_imgtype.”)#i”, $imgfile_name)) { // 拒绝上传 }这个正则#\.(jpg|gif|png)#i的意思是在文件名中任意位置寻找一个点号后面紧跟jpggif或png。对于shell.png.pHp这个文件名它成功匹配到了.png部分于是检查通过系统认为这是一个合法的PNG图片文件允许上传。至于后面多余的.pHp这段检查逻辑完全无视了。这就是典型的“中间匹配”而非“末尾匹配”导致的问题。攻击者通过在合法后缀后面追加恶意后缀.pHp轻松绕过了白名单检查。而前面那行过滤特殊字符的代码因为点号不在过滤列表内形同虚设。整个防御链条被彻底击穿。4. 官方修复方案与局限性在漏洞被披露后DedeCMS官方迅速给出了修复方案。修复方式正是针对我们上面分析的检查逻辑。官方建议修改/include/dialog/select_images_post.php文件中的后缀检查代码修改前if(!preg_match(“#\.(“.$cfg_img_type.”)#i”, $imgfile_name))修改后if(!preg_match(“#\.(“.$cfg_img_type.”)$#i”, $imgfile_name))区别仅仅是在正则表达式的末尾加了一个$符号。这个$符号在正则中表示“字符串的结尾”。这样一来正则#\.(jpg|gif|png)$#i的要求就变成了文件名必须以点号加允许的图片后缀结尾。对于shell.png.pHp因为它以.pHp结尾无法匹配.jpg|.gif|.png中的任何一个因此会被果断拒绝。这个修复方案直击要害简单有效确实堵住了这个特定的绕过路径。但是从更高的安全标准来看它仍然存在一些局限性依赖单一检查点安全防御应该是多层次的。仅仅加强一个正则表达式如果其他地方存在逻辑问题比如文件内容检查、目录权限设置依然可能被其他手法绕过。未处理文件内容修复方案只检查了文件名没有涉及文件内容的校验。攻击者仍然可以上传一个内容完全是PHP代码但后缀名为.jpg的文件。如果服务器存在其他解析漏洞比如Apache的AddType配置错误、Nginx的畸形路径解析漏洞这个文件仍可能被当作PHP执行。未强制重命名最安全的做法是服务器接收到文件后完全忽略用户上传时的文件名自己按照一定规则如md5(时间戳随机数).jpg重新生成文件名。这样可以从根本上杜绝所有基于文件名的攻击。所以官方的补丁是一个合格的“紧急止血”方案但还不是一个“强健免疫”的方案。对于追求更高安全性的项目我们需要做得更多。5. 深度加固构建多层次防御体系基于多年的实战经验我总结了一套针对文件上传功能的深度加固方案。这套方案不是简单地打一个补丁而是从多个层面构建防御体系让攻击者无从下手。第一层防御强化后缀名验证官方的$结尾匹配是基础我们可以做得更严格。建议采用“黑名单白名单”结合并以白名单为主的方式。// 定义严格的白名单只允许真正的图片后缀 $allowed_ext array(‘jpg’, ‘jpeg’, ‘gif’, ‘png’, ‘bmp’); // 获取文件后缀并转为小写 $file_ext strtolower(pathinfo($filename, PATHINFO_EXTENSION)); // 白名单校验 if(!in_array($file_ext, $allowed_ext)) { die(‘文件类型不允许’); } // 额外的正则校验防止双后缀等畸形名 if(preg_match(‘/\.(php|asp|jsp|sh|pl|py|cgi)/i’, $filename)) { die(‘文件名包含危险后缀’); }第二层防御文件内容类型检查这是绕过文件名检查的常用手段的克星。我们不能相信HTTP请求头中的Content-Type如image/jpeg因为它可以被轻易篡改。应该使用服务器端函数检测文件的真实类型。// 使用getimagesize函数检查是否为真实图片 $image_info getimagesize($_FILES[‘file’][‘tmp_name’]); if($image_info false) { die(‘上传的不是有效的图片文件’); } // $image_info[‘mime’] 会返回真实的MIME类型如 ‘image/jpeg’ $allowed_mime array(‘image/jpeg’, ‘image/png’, ‘image/gif’); if(!in_array($image_info[‘mime’], $allowed_mime)) { die(‘MIME类型不允许’); }对于非图片文件的上传可以使用finfo_file函数Fileinfo扩展进行更广泛的MIME类型检测。第三层防御强制重命名与目录隔离这是至关重要的一步。上传的文件绝对不能使用用户提供的原始文件名。// 生成随机文件名 $new_filename md5(uniqid() . mt_rand()) . ‘.’ . $file_ext; // 定义存储路径最好放在Web根目录之外或使用 .htaccess / Nginx规则禁止执行脚本 $upload_dir ‘/path/to/upload/’ . date(‘Ym’) . ‘/’; // 按年月分目录 if(!is_dir($upload_dir)) { mkdir($upload_dir, 0755, true); } $destination $upload_dir . $new_filename;同时务必在存储目录下放置禁止脚本执行的规则文件。对于Apache可以放置.htaccess文件内容为FilesMatch “\.(php|php5|php7|asp|aspx|jsp|pl|py)$” Order Deny,Allow Deny from all /FilesMatch对于Nginx则需要在服务器配置的location块中添加location ~* ^/uploads/.*\.(php|php5|php7)$ { deny all; }第四层防御图片二次处理内容重写对于图片上传最彻底的防御是进行“再编码”。即使用GD库或ImageMagick将上传的图片重新保存一遍。// 接在getimagesize验证之后 switch($image_info[‘mime’]) { case ‘image/jpeg’: $src_img imagecreatefromjpeg($tmp_file); imagejpeg($src_img, $destination, 90); // 以90%质量重新保存为JPEG break; case ‘image/png’: $src_img imagecreatefrompng($tmp_file); imagepng($src_img, $destination); break; case ‘image/gif’: $src_img imagecreatefromgif($tmp_file); imagegif($src_img, $destination); break; } imagedestroy($src_img);这个过程会剥离所有嵌入在文件末尾或元数据如EXIF中的额外数据只保留纯粹的图像数据。任何附加在图片里的恶意代码都会被彻底清除。第五层防御文件大小与尺寸限制除了类型还要对文件大小和图片尺寸做合理限制防止拒绝服务攻击DoS或超大图片消耗资源。// 限制文件大小例如2MB $max_size 2 * 1024 * 1024; if($_FILES[‘file’][‘size’] $max_size) { die(‘文件大小超过限制’); } // 限制图片尺寸 $max_width 1920; $max_height 1080; if($image_info[0] $max_width || $image_info[1] $max_height) { die(‘图片尺寸超过限制’); }把这五层防御像洋葱一样一层层包裹在你的上传功能上攻击者想要突破难度就呈指数级增长了。每一层都可能拦住一类攻击手法。在实际项目中你可能不需要全部实施但至少要做到“白名单校验强制重命名目录禁执行”这个铁三角。安全没有银弹但扎实的防御基本功能帮你挡住99%的自动化攻击和大部分手动测试。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2408251.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…