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

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

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%的自动化攻击和大部分手动测试。

相关文章:

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

1. 漏洞背景与环境搭建 大家好,我是老张,一个在安全圈摸爬滚打了十来年的老兵。今天想和大家深入聊聊一个经典的CMS漏洞——DedeCMS V5.7 SP2的前台文件上传漏洞。这个漏洞虽然官方早就出了补丁,但它的成因和绕过手法非常典型,直到…...

5个LibreSprite图层与帧管理的高效工作流:像素艺术制作终极指南

5个LibreSprite图层与帧管理的高效工作流:像素艺术制作终极指南 【免费下载链接】LibreSprite Animated sprite editor & pixel art tool -- Fork of the last GPLv2 commit of Aseprite 项目地址: https://gitcode.com/gh_mirrors/li/LibreSprite Libre…...

从零构建Zabbix监控H3C交换机:手把手教你定位关键OID

1. 为什么你需要自己动手找OID? 很多刚开始接触Zabbix监控H3C交换机的朋友,第一反应就是去网上找现成的模板。这想法没错,但现实往往很骨感。我这些年折腾过不少H3C的设备,从老款的S5120到新的S6800系列,一个深刻的体会…...

终极指南:Agent Zero AI框架的抽象类设计与接口规范

终极指南:Agent Zero AI框架的抽象类设计与接口规范 【免费下载链接】agent-zero Agent Zero AI framework 项目地址: https://gitcode.com/GitHub_Trending/ag/agent-zero Agent Zero AI framework是一个强大的人工智能开发框架,它通过抽象类设计…...

深入解析USB接口类型:从Type-A到Type-C的演变与应用场景

1. 从“万能”到“万能”:USB接口的进化之路 不知道你有没有这样的经历,在抽屉里翻箱倒柜,只为找一根能给手机充电的线,结果翻出来一堆形状各异的USB线,有的头大,有的头小,有的扁,有…...

Wan2GP V14版 - 低显存畅享AI视频创作,深度优化Qwen-Image模型 兼容多代显卡 一站式整合包发布

1. 低显存AI视频创作,这次真的“飞入寻常百姓家”了 朋友们,最近是不是又被各种炫酷的AI生成视频刷屏了?看着别人用几句话、几张图就变出电影级的短片,心里痒痒的,但一想到自己那“年事已高”的显卡,还有动…...

深度学习顶会背后的城市密码:从CVPR选址看科技产业分布(附参会签证攻略)

深度学习顶会的城市叙事:选址背后的科技产业逻辑与参会实战指南 每次翻开CVPR、ICCV或ECCV的会议通知,看到举办城市那一栏,你是否也曾有过一丝好奇:为什么是这里?是西雅图的海风,蒙特利尔的法语区风情&…...

车载AAOS系统Android CarService接口定义全链路设计之车载语音助手为例

采用 AAOS 的车载 Android 系统,一次性集成即可让车规硬件直接运行完整 Android 生态,通过 CarService 深度控制空调、车窗等车控功能,使车载的接口标准化规范化,显著缩短开发周期、降低维护成本并拓展持续盈利空间,下…...

Windows下Sourcetree安装与基础Git操作指南(适合SVN转Git的新手)

从SVN到Git的平滑过渡:Sourcetree可视化实战指南 如果你和我一样,职业生涯的前半段是在SVN的“集中式”世界里度过的,那么初次接触Git时,那种面对命令行和分布式概念的茫然感,我深有体会。在SVN里,一切井然…...

Lab4AI上线一键部署OpenClaw,附2分钟云养虾指南

Lab4AI上线一键部署OpenClaw,附2分钟云养虾指南 “养虾”这件事,最近很火。 在 AI 自动化工具高速发展的今天,OpenClaw 作为一款开源 AI 代理与自动化平台,正以其出色的灵活性和兼容性,成为许多人打造专属智能助手的优…...

DSP设备唯一ID深度应用:基于UID_REGS实现防克隆与license控制

DSP设备唯一ID深度应用:基于UID_REGS实现防克隆与license控制 在工业物联网和高端嵌入式设备领域,设备身份的唯一性与软件授权的安全性,已经从“锦上添花”变成了“生存底线”。想象一下,你投入巨资研发的电机控制算法&#xff0c…...

SyzVegas复现避坑指南:从零搭建内核模糊测试环境(Ubuntu 16.04 + QEMU)

SyzVegas内核模糊测试实战:从零到一搭建与深度调优指南 如果你是一位对操作系统内核安全研究充满热情,或是希望复现顶会论文成果的开发者,那么“SyzVegas”这个名字很可能已经出现在你的待办清单里。这篇发表在USENIX Security上的论文&#…...

Schej.it与Google Calendar集成教程:无缝同步你的日程安排

Schej.it与Google Calendar集成教程:无缝同步你的日程安排 【免费下载链接】timeful.app schej helps you quickly find the best time for your group to meet. Its like When2meet with Google Calendar integration! 项目地址: https://gitcode.com/gh_mirrors…...

NanoBoyAdvance核心技术解析:PPU渲染引擎如何实现逐周期模拟

NanoBoyAdvance核心技术解析:PPU渲染引擎如何实现逐周期模拟 【免费下载链接】NanoBoyAdvance A cycle-accurate Nintendo Game Boy Advance emulator. 项目地址: https://gitcode.com/gh_mirrors/na/NanoBoyAdvance NanoBoyAdvance作为一款 cycle-accurate …...

解决NAT实例痛点:alterNAT自动故障转移与健康检查实现

解决NAT实例痛点:alterNAT自动故障转移与健康检查实现 【免费下载链接】alternat High availability implementation of AWS NAT instances. 项目地址: https://gitcode.com/gh_mirrors/al/alternat 在AWS云环境中,NAT设备是私有子网访问互联网的…...

深入理解linux-malware项目:恶意软件样本库与威胁情报应用

深入理解linux-malware项目:恶意软件样本库与威胁情报应用 【免费下载链接】linux-malware Tracking interesting Linux (and UNIX) malware. Send PRs 项目地址: https://gitcode.com/gh_mirrors/li/linux-malware 在网络安全领域,恶意软件分析是…...

如何利用missing-semester-cn.github.io进行机器自省:终极系统监控指南

如何利用missing-semester-cn.github.io进行机器自省:终极系统监控指南 【免费下载链接】missing-semester-cn.github.io the CS missing semester Chinese version 项目地址: https://gitcode.com/gh_mirrors/mi/missing-semester-cn.github.io missing-sem…...

Symfony Translation与Jenkins Pipeline集成:实现自动化多语言部署的终极指南

Symfony Translation与Jenkins Pipeline集成:实现自动化多语言部署的终极指南 【免费下载链接】translation symfony/translation: 是一个用于 PHP 的翻译库,支持多种消息源和翻译格式,可以用于构建多语言的 Web 应用程序和 API。 项目地址…...

终极指南:esbuild v0.25.3如何实现构建效率与稳定性的双重突破

终极指南:esbuild v0.25.3如何实现构建效率与稳定性的双重突破 【免费下载链接】esbuild An extremely fast bundler for the web 项目地址: https://gitcode.com/GitHub_Trending/es/esbuild esbuild作为一款极速的Web打包工具,在v0.25.3版本中实…...

Redux-actions终极指南:10个实用工具函数快速简化Redux开发

Redux-actions终极指南:10个实用工具函数快速简化Redux开发 【免费下载链接】redux-actions Flux Standard Action utilities for Redux. 项目地址: https://gitcode.com/gh_mirrors/re/redux-actions Redux-actions是一套Flux标准动作工具库,专为…...

GSL项目贡献终极指南:如何为C++核心库提交代码的完整流程

GSL项目贡献终极指南:如何为C核心库提交代码的完整流程 【免费下载链接】GSL Guidelines Support Library 项目地址: https://gitcode.com/gh_mirrors/gs/GSL Guidelines Support Library(GSL)是C Core Guidelines推荐使用的核心库&am…...

HumHub企业社交网络:如何快速搭建内部协作平台的终极指南

HumHub企业社交网络:如何快速搭建内部协作平台的终极指南 【免费下载链接】humhub HumHub is an Open Source Enterprise Social Network. Easy to install, intuitive to use and extendable with countless freely available modules. 项目地址: https://gitcod…...

如何使用Mariana Trench快速发现Android应用中的远程代码执行漏洞

如何使用Mariana Trench快速发现Android应用中的远程代码执行漏洞 【免费下载链接】mariana-trench A security focused static analysis tool for Android and Java applications. 项目地址: https://gitcode.com/gh_mirrors/ma/mariana-trench Mariana Trench是一款专…...

AutoPhrase多语言支持详解:从英语到中文的无缝切换方案

AutoPhrase多语言支持详解:从英语到中文的无缝切换方案 【免费下载链接】AutoPhrase AutoPhrase: Automated Phrase Mining from Massive Text Corpora 项目地址: https://gitcode.com/gh_mirrors/au/AutoPhrase AutoPhrase是一款强大的自动化短语挖掘工具&a…...

如何利用Golden Layout虚拟组件技术打造高性能Web应用布局管理系统

如何利用Golden Layout虚拟组件技术打造高性能Web应用布局管理系统 【免费下载链接】golden-layout A multi window layout manager for webapps 项目地址: https://gitcode.com/gh_mirrors/go/golden-layout Golden Layout是一款功能强大的Web应用多窗口布局管理器&…...

Shodan搜索查询的终极优化策略:基于Awesome Shodan Queries的性能调优指南

Shodan搜索查询的终极优化策略:基于Awesome Shodan Queries的性能调优指南 【免费下载链接】awesome-shodan-queries 🔍 A collection of interesting, funny, and depressing search queries to plug into shodan.io 👩‍💻 项…...

arXiv LaTeX Cleaner 终极指南:从文件扫描到代码替换的完整揭秘

arXiv LaTeX Cleaner 终极指南:从文件扫描到代码替换的完整揭秘 【免费下载链接】arxiv-latex-cleaner arXiv LaTeX Cleaner: Easily clean the LaTeX code of your paper to submit to arXiv 项目地址: https://gitcode.com/gh_mirrors/ar/arxiv-latex-cleaner …...

如何提升JUnit4测试效率:测试用例优先级算法终极指南

如何提升JUnit4测试效率:测试用例优先级算法终极指南 【免费下载链接】junit4 A programmer-oriented testing framework for Java. 项目地址: https://gitcode.com/gh_mirrors/ju/junit4 JUnit4作为Java程序员最常用的测试框架,其测试用例的执行…...

【MySQL】在RHEL9上使用通用二进制包部署mysql教程

本篇博客将介绍如何使用通用二进制包在RHEL9上部署mysql,包括二进制包的下载,官方文档的查看以及配置等等。第一步:前往官网下载mysql通用二进制包官网:www.mysql.com进入官网后点击downloads然后划到下面点击社区版下载然后选择社…...

CTFshow系列——PHP特性Web105-108

今天讲解的是PHP的Web105-108题目解析讲解 文章目录Web105(新题型)分析代码构造Payload思路:最终payload:Web106Web107代码分析方法一:PHP弱类型比较方法二:直接使v3的md5值等于v1Web108代码要点&#xff0…...