某开源项目管理软件 命令执行漏洞分析
字数 1249 2025-08-06 12:21:08

禅道项目管理软件命令执行漏洞分析报告

漏洞概述

禅道项目管理软件存在一处命令执行漏洞,攻击者通过构造特定请求可在服务器上执行任意命令。该漏洞存在于代码仓库管理模块中,通过不安全的exec()函数调用实现命令注入。

影响版本

  • 开源版: 17.4 ~ 18.0.beta1
  • 旗舰版: 3.4 ~ 4.0.beta
  • 企业版: 7.4 ~ 8.0beta1, 8.0beta2

利用条件

  • 拥有代码库的创建及编辑权限
  • 能够发送HTTP请求到目标系统

环境搭建

  1. 下载受影响版本的禅道源码:

    https://www.zentao.net/dl/zentao/18.0.beta1/ZenTaoPMS.18.0.beta1.php7.2_7.4.zip
    
  2. 配置PHP 7.3.4环境

  3. 配置IDEA PHP debug环境(参考:IDEA PHP Debug配置

漏洞分析

路由规则

禅道的路由规则为:

/index.php?m=文件夹名&f=方法名

例如访问/module/admin/control.phpindex方法,可使用路由:

/index.php?m=admin&f=index

漏洞点

漏洞位于module\repo\model.php文件中的checkConnection函数:

function checkConnection()
{
    if($this->post->scm == 'Subversion') {
        $versionCommand = "$client --version --quiet 2>&1";
        exec($versionCommand, $versionOutput, $result);
        // ...
    }
    // ...
}

当POST参数scm=Subversion时,会进入if语句执行exec函数。$client变量被直接拼接到命令中,导致命令注入。

利用链分析

  1. 调用链:

    • model.php中的checkConnection函数不能直接调用
    • 有三处调用了checkConnection,都在model.phpupdate函数中
    • 需要在control.php中寻找调用model.phpupdate()函数的地方
  2. 触发点:

    • \module\repo\control.phpedit函数可以触发model.phpupdate函数
    • 但需要先通过create创建一个仓库才能进行编辑

漏洞复现步骤

1. 创建代码仓库

  1. 登录禅道后台
  2. 点击左侧"DevOps" -> 创建代码仓库
  3. 抓包修改请求:
    • 将报文中的serviceProject修改为非0值
    • 成功创建后会返回repoIDobjectID信息

2. 编辑仓库触发漏洞

  1. 复制创建请求到重放模块

  2. 修改请求:

    • f=create替换为f=edit
    • URL中增加参数:&repoID=[编号]&objectID=[编号](使用创建时返回的值)
    • POST请求body修改为:SCM=Subversion&client=[恶意命令]

    例如:

    SCM=Subversion&client=calc
    
  3. 发送请求后,由于module\repo\model.php中调用了两次checkConnection()函数,会执行两次命令(如示例中会弹出两个计算器)

技术细节

  1. 命令注入原理:

    • $client变量未经过滤直接拼接到命令字符串中
    • 通过exec()函数执行拼接后的命令
  2. 利用限制:

    • 需要登录且有代码库管理权限
    • 需要先创建仓库才能编辑触发漏洞
  3. 防御建议:

    • $client变量进行严格过滤
    • 使用白名单限制可执行的命令
    • 升级到修复版本

参考链接

  1. 漏洞分析原文
  2. 微信公众号分析
禅道项目管理软件命令执行漏洞分析报告 漏洞概述 禅道项目管理软件存在一处命令执行漏洞,攻击者通过构造特定请求可在服务器上执行任意命令。该漏洞存在于代码仓库管理模块中,通过不安全的 exec() 函数调用实现命令注入。 影响版本 开源版 : 17.4 ~ 18.0.beta1 旗舰版 : 3.4 ~ 4.0.beta 企业版 : 7.4 ~ 8.0beta1, 8.0beta2 利用条件 拥有代码库的创建及编辑权限 能够发送HTTP请求到目标系统 环境搭建 下载受影响版本的禅道源码: 配置PHP 7.3.4环境 配置IDEA PHP debug环境(参考: IDEA PHP Debug配置 ) 漏洞分析 路由规则 禅道的路由规则为: 例如访问 /module/admin/control.php 的 index 方法,可使用路由: 漏洞点 漏洞位于 module\repo\model.php 文件中的 checkConnection 函数: 当POST参数 scm=Subversion 时,会进入if语句执行 exec 函数。 $client 变量被直接拼接到命令中,导致命令注入。 利用链分析 调用链 : model.php 中的 checkConnection 函数不能直接调用 有三处调用了 checkConnection ,都在 model.php 的 update 函数中 需要在 control.php 中寻找调用 model.php 的 update() 函数的地方 触发点 : \module\repo\control.php 的 edit 函数可以触发 model.php 的 update 函数 但需要先通过 create 创建一个仓库才能进行编辑 漏洞复现步骤 1. 创建代码仓库 登录禅道后台 点击左侧"DevOps" -> 创建代码仓库 抓包修改请求: 将报文中的 serviceProject 修改为非0值 成功创建后会返回 repoID 和 objectID 信息 2. 编辑仓库触发漏洞 复制创建请求到重放模块 修改请求: 将 f=create 替换为 f=edit URL中增加参数: &repoID=[编号]&objectID=[编号] (使用创建时返回的值) POST请求body修改为: SCM=Subversion&client=[恶意命令] 例如: 发送请求后,由于 module\repo\model.php 中调用了两次 checkConnection() 函数,会执行两次命令(如示例中会弹出两个计算器) 技术细节 命令注入原理 : $client 变量未经过滤直接拼接到命令字符串中 通过 exec() 函数执行拼接后的命令 利用限制 : 需要登录且有代码库管理权限 需要先创建仓库才能编辑触发漏洞 防御建议 : 对 $client 变量进行严格过滤 使用白名单限制可执行的命令 升级到修复版本 参考链接 漏洞分析原文 微信公众号分析