影响版本

禅道 版本
开源版 17.4 ~ 18.0.beta1
旗舰版 3.4 ~ 4.0.beta
企业版 7.4 ~ 8.0beta1 8.0beta2

利用条件

代码库的创建及编辑权限

环境搭建

下载源码版本,本地复现时使用的是PHP 7.3.4环境

https://www.zentao.net/dl/zentao/18.0.beta1/ZenTaoPMS.18.0.beta1.php7.2_7.4.zip

IDEA PHP debug环境配置可以参考下方的文章

https://smallfox233.github.io/%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE/IDEA/PHP%20Debug/

漏洞分析

路由规则

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

若需要访问/module/admin/control.php的index方法,可使用如下路由(该路由需要登录后)

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

通过debug就可以知道是否访问了该方法

漏洞点

漏洞位置为module\repo\model.phpcheckConnection函数

类型为POST

传入参数scm=Subversion可进入if语句中执行exec函数

变量client被拼接到了versionCommand变量,后经exec函数调用执行

寻找利用链

在model.php中的函数不能直接通过发送请求进行调用,在control.php中的函数才可以

有三处地方调用了函数checkConnection,都是在model.php中

第二处和第三处中都在model.php的update函数中

所以后续的利用链只需经过update函数,都会进入漏洞点

之后需要在control.php中寻找能够调用mode.php 的update()函数的地方

直接检索时,没法获取对应的调用点

触发点

之后经过查询和debug调试发现\module\repo\control.php的edit可触发model.php的update函数

而edit函数需要先通过create创建一个仓库才能进行编辑

利用链

漏洞复现

创建代码仓库

先登录后台

点击左侧的DevOps创建一个代码仓库

抓包发送,出现了一个报错

根据报错提示修改

将报文中的serviceProject修改为非0值即可成功创建代码仓库,创建成功后会返回repoID和objectID信息

编辑仓库触发漏洞

将请求包复制一个到重放模块中修改

f=create替换为f=edit

在url中增加如下的内容,将这两个参数值提换成创建成功后返回的值

1
&repoID=编号&objectID=编号

再替换post请求body信息

1
SCM=Subversion&client=calc

因为在module\repo\model.php中调用了两次的checkConnection()函数

所以发包后将会执行两次calc命令,将会弹出两个计算器

参考

https://mp.weixin.qq.com/s?__biz=MzkzNjMxNDM0Mg==&mid=2247485644&idx=1&sn=4bfa7d4ec2944dfa8755cc26b0454aa8&chksm=c2a1dc45f5d655534fe3205299ace389b080f51ce5ec3698cf1690c49171024b27cbfba4fa8d&mpshare=1&scene=1&srcid=0113dD9gKGwuztrYNWfTSAOh&sharer_sharetime=