DCRCMS文件上传漏洞复现与防御实战(CNVD-2020-27175)

DCRCMS文件上传漏洞复现与防御实战(CNVD-2020-27175) 1. 从一次“意外”说起为什么文件上传漏洞这么危险大家好我是老张在安全圈里摸爬滚打了十几年见过太多因为“小疏忽”导致“大事故”的案例。今天想和大家聊的这个DCRCMS文件上传漏洞就是一个非常典型、也极其危险的例子。你可能觉得一个企业站系统不就是上传个图片、传个文档吗能出多大问题我告诉你问题大了去了。这个漏洞的编号是CNVD-2020-27175听起来有点官方但它的本质很简单攻击者能通过后台的一个功能把一段恶意的PHP代码伪装成图片传上去然后服务器就会傻乎乎地把它当成一个可执行的脚本文件来运行。一旦成功攻击者就拿到了你服务器的“钥匙”可以看你的数据库、删你的文件甚至把你的服务器变成“矿机”或者“肉鸡”。这就像你家小区的门禁系统本来只允许业主刷脸进入结果保安不看脸只看你手里拿的是不是一张“卡片形状”的东西。于是攻击者随便打印一张纸画个卡片的轮廓保安就放行了。进来之后他就可以为所欲为。DCRCMS这个漏洞就是这个“保安”的逻辑出了问题。它没有认真检查你上传的文件到底是不是一张真正的“图片”即合法的文件内容而只是看了一眼文件上传时自报的“家门”即HTTP请求头中的Content-Type字段。你说这有多危险所以无论你是这个系统的开发者、运维人员还是正在使用它的企业站长理解这个漏洞的来龙去脉知道怎么复现它以便于测试自家系统更要知道如何彻底堵上它这是至关重要的安全必修课。下面我就带大家手把手走一遍攻击者的视角看看这个漏洞是怎么被利用的然后我们再站在防御者的角度聊聊怎么把自家的“门”焊死。2. 实战复现一步步“攻破”有漏洞的DCRCMS光说不练假把式咱们直接上手。为了安全且合法地学习请务必在你自己完全可控的虚拟机或隔离测试环境中进行以下操作比如使用VirtualBox搭建的本地靶场。千万不要对任何线上系统进行未授权的测试2.1 搭建漏洞环境首先我们需要一个有漏洞的DCRCMS版本。经过验证1.1.5版本是存在这个问题的。你可以在一些开源漏洞靶场平台或者历史软件存档站点找到这个版本的安装包。拿到手后把它部署在你的PHPMySQL或SQLite环境里。我用的是PHP 5.4MySQL 5.7的环境兼容性比较好。安装过程就是常规的Web安装数据库配置好管理员账号设置好默认后台地址通常是/dcr/目录下这里就不赘述了。安装成功后访问你的站点IP和端口应该能看到稻草人企业站的默认首页。我们的“攻击”起点就是那个看似无害的后台新闻发布功能。2.2 潜入后台与准备“武器”第一步访问后台登录页比如http://你的靶机IP:端口/dcr/login.htm。使用默认或你安装时设置的管理员账号密码原始文章提到默认是admin/123456登录。成功进入后台后找到“新闻管理”或类似的功能模块。通常为了上传新闻图片系统会提供一个文件上传点。我们的目标就是这里。接下来准备我们的“武器”——一个PHP一句话木马。这句话非常短小精悍但威力巨大。创建一个文本文件将其后缀改为.php内容如下?php eval($_POST[cmd]);?这行代码的意思是执行通过POST请求传递过来的名为cmd的参数的值。如果攻击者传递cmdsystem(whoami);服务器就会执行whoami命令并返回结果。这就是所谓的“一句话木马”因为它只需要一句话就能提供一个Web端的命令执行接口。但是直接上传一个.php文件系统很可能会因为后缀名不在允许列表如.jpg, .png, .gif内而拒绝。所以我们需要一点“伪装”。2.3 关键一步利用Burp Suite进行请求篡改这是整个漏洞利用的核心环节也是它被称为“文件上传漏洞”而非“直接上传木马”的原因。我们不会傻乎乎地在网页上点上传然后指望系统放过我们的.php文件。我们要“骗”过它。正常操作触发上传在后台的“添加新闻”页面找到图片上传按钮。不要直接选择我们刚写的.php文件而是先选择一个真实的、无害的图片文件比如一张.jpg格式的风景图。点击上传。此时打开你早已准备好的抓包工具——Burp Suite。拦截HTTP请求确保Burp Suite的代理Proxy功能是开启的并且你的浏览器已经配置好代理指向Burp。当你点击网页上的“上传”或“添加新闻”按钮时Burp Suite会拦截到浏览器发送给服务器的HTTP请求。解剖请求包在Burp Suite的Proxy - Intercept标签页下你会看到一个被拦截的POST请求。这个请求体是“multipart/form-data”格式的里面包含了新闻标题、内容等表单字段最关键的是有一个文件上传的字段。你会看到类似这样的内容-----------------------------1234567890 Content-Disposition: form-data; namefile; filenamenormal.jpg Content-Type: image/jpeg [这里是图片文件的二进制数据]注意看Content-Type: image/jpeg这一行。这是浏览器根据文件后缀名自动生成的告诉服务器“我上传的是一个jpeg图片哦”。施展“魔术”现在我们要做两件“坏事”替换文件内容在Burp Suite的拦截界面找到文件二进制数据的那部分就是[这里是图片文件的二进制数据]那里。我们需要用我们的PHP一句话木马的代码替换掉原来的图片数据。但是直接粘贴文本不行因为服务器期待的是文件二进制流。更简单的方法是先修改filename。把filenamenormal.jpg改成filenameshell.php。然后在二进制数据区域直接右键选择“Paste from file”选择我们之前写好的那个shell.php文件。这样实际发送的文件内容就变成了我们的木马代码。维持伪装虽然我们把文件名和内容都换成了PHP木马但我们保留甚至说必须保留Content-Type: image/jpeg这一行不变这就是漏洞的精髓所在DCRCMS的验证逻辑很可能只检查了这个Content-Type头发现是image/jpeg就以为上传的是合法图片于是放行并按照文件名shell.php保存到了服务器上。放行请求完成上述修改后点击Burp Suite的“Forward”按钮将这个被篡改的请求发送给服务器。2.4 寻找与连接获取服务器控制权如果漏洞存在且我们的操作正确服务器会返回一个成功的响应比如图片上传成功并返回一个访问路径。这个路径通常包含上传日期和随机生成的文件名例如/uploads/news/2024_01_24/2401240901106638.php。现在最“激动人心”也是最具破坏性的一步来了。攻击者会使用中国蚁剑AntSword这样的Webshell管理工具。在蚁剑中添加一个新的数据URL就填我们刚刚得到的那个路径http://你的靶机IP:端口/uploads/news/2024_01_24/2401240901106638.php。连接密码就是我们一句话木马里设定的cmd即POST参数名。点击连接。如果一切顺利蚁剑的界面会瞬间打开左边是服务器的目录树右边可以执行命令、浏览文件、上传下载数据。这意味着攻击者已经完全掌控了这台Web服务器。他可以查看配置文件窃取数据库密码可以植入勒索病毒可以将其作为跳板攻击内网其他机器。危害程度不言而喻。3. 漏洞根源深度剖析不仅仅是“没检查后缀名”复现完了感觉很刺激但作为开发和安全人员我们更需要冷静下来思考问题到底出在哪很多人第一反应是“文件后缀名没过滤”。对DCRCMS这个案例来说这只是一部分原因而且不是最根本的。根本原因在于信任了客户端传来的、完全可被篡改的数据。具体拆解为三层前端验证形同虚设很多系统只在网页上用JavaScript检查了文件后缀名。这种检查对于普通用户是友好的提示但对于攻击者用Burp Suite一抓包一改包就轻松绕过。安全绝不能依赖前端验证。后端验证逻辑致命缺陷这是CNVD-2020-27175漏洞的核心。从复现过程看后端代码可能只做了类似这样的检查if ($_FILES[file][type] image/jpeg || $_FILES[file][type] image/png) { // 允许上传 move_uploaded_file($_FILES[file][tmp_name], $target_path); }这里的$_FILES[file][type]值直接来源于HTTP请求头中的Content-Type是攻击者可以随意伪造的。攻击者上传一个.php文件但把Content-Type改成image/jpeg就轻松骗过了这个检查。正确的做法是使用服务器的文件检测函数如PHP的getimagesize()或者通过文件头魔数Magic Number来判断文件真实类型。一个JPEG图片的文件开头字节是FF D8 FF E0而PHP文件的开头是3C 3F 70 68 70即?php这是无法通过改个请求头就伪造的。文件名处理不当即使文件内容检查了如果文件名处理不好也会留隐患。比如系统允许上传.jpg文件但攻击者上传一个名为shell.php.jpg的文件。如果服务器配置如Apache的mod_rewrite或某些解析漏洞导致文件被当作.php执行那就危险了。更佳实践是上传后由服务器生成一个随机的、无后缀争议的新文件名如uuid来存储并通过数据库记录原始文件名和真实文件类型。4. 全面防御指南让你的文件上传功能固若金汤知道了漏洞怎么产生的修复起来就有了方向。防御不是打一个补丁就完事而是一套组合拳。我结合多年经验给你梳理一个从代码到运维的完整防御方案。4.1 代码层防御治本之策这是开发人员必须做到的底线。在你的上传处理代码中请务必实现以下所有点白名单验证文件扩展名这是最基本但必须做的。只允许一组明确的、安全的扩展名如.jpg,.jpeg,.png,.gif。绝对禁止使用黑名单因为你永远不知道有多少种奇怪的扩展名或大小写变形.pHp, .phtml, .jPg等可以绕过。$allowed_ext [jpg, jpeg, png, gif]; $uploaded_ext strtolower(pathinfo($_FILES[file][name], PATHINFO_EXTENSION)); if (!in_array($uploaded_ext, $allowed_ext)) { die(文件类型不允许); }验证文件真实类型MIME类型使用服务器端函数检测文件内容的实际类型而不是相信$_FILES[file][type]。// 使用getimagesize检查是否为真实图片非图片文件会返回false $image_info getimagesize($_FILES[file][tmp_name]); if ($image_info false) { die(上传的不是有效的图片文件); } // $image_info[mime] 会返回真实的MIME类型如image/jpeg $allowed_mime [image/jpeg, image/png, image/gif]; if (!in_array($image_info[mime], $allowed_mime)) { die(图片MIME类型不允许); }对于非图片文件如PDF可以使用finfo_file()函数Fileinfo扩展来检测。重命名上传文件不要使用用户上传时的原始文件名。建议使用“随机字符串 白名单内后缀”的方式。$new_filename uniqid() . _ . md5(microtime(true)) . . . $uploaded_ext; $target_path /path/to/uploads/ . $new_filename;这样即使攻击者绞尽脑汁构造了特殊文件名最终在服务器上也只是像5f8a1b2c3d4e5.jpg这样的名字无法直接访问或利用。设置独立的、无执行权限的存储目录这是至关重要的一步。通过Web服务器如Nginx/Apache的配置确保上传文件所在的目录禁止执行任何脚本。Nginx配置示例location ^~ /uploads/ { deny all; } location ~* ^/uploads/.\.(jpg|jpeg|png|gif)$ { allow all; }或者更简单地在存放上传文件的目录下放置一个.htaccess文件针对Apache或直接在服务器配置中为该目录设置php_flag engine off。4.2 服务器与运维层加固纵深防御代码写好了服务器环境也得跟上形成纵深防御。定期更新与补丁像DCRCMS这样的开源系统官方在漏洞曝光后通常会发布新版本或补丁。第一时间更新到最新稳定版是最简单有效的办法。对于不再维护的旧系统要么迁移要么自己手动修补漏洞代码。配置安全的Web服务器如前所述严格限制上传目录的权限。确保运行Web服务的用户如www-data, nginx对上传目录只有写入权限没有执行权限。同时关闭不必要的HTTP方法如PUT, DELETE。使用Web应用防火墙WAF在应用前端部署WAF可以拦截常见的攻击payload包括利用文件上传漏洞的请求。虽然不能完全依赖但能增加一层防护。文件内容二次检查对于图片可以在服务器端使用GD库或Imagick进行图片重采样/重置。即使攻击者将一个PHP代码嵌入到图片的EXIF信息中一种隐藏攻击手段经过重采样生成一张全新的图片这些非像素数据也会被清除掉。隔离与监控将上传功能部署在独立的子域名或服务上与主站隔离。同时建立日志监控对上传异常行为如短时间内大量上传、尝试上传非常规后缀进行告警。4.3 针对DCRCMS CNVD-2020-27175漏洞的紧急修复如果你正在使用受影响的DCRCMS 1.1.5版本又暂时无法升级可以尝试手动定位修复。你需要找到处理文件上传的PHP代码文件通常在后台模块的某个.php文件中。搜索move_uploaded_file、$_FILES等关键字。找到后用上面4.1节提到的“白名单真实MIME检测重命名”的代码替换掉原来简单的类型检查逻辑。这是一个临时解决方案长远来看迁移到安全的版本或系统才是正道。文件上传功能是Web应用的常见需求但也一直是安全的重灾区。CNVD-2020-27175这个漏洞给我们敲响了警钟安全无小事任何一个看似微小的信任都可能成为整个系统沦陷的起点。作为开发者要在编码时就绷紧安全这根弦作为运维者要构建多层次的防御体系。希望这篇从攻击到防御的详细拆解能让你不仅“看懂”了这个漏洞更能真正“掌握”防御它的方法在实际工作中搭建起更稳固的安全防线。