禅道的前世今生-上

admin 2025年1月9日15:30:41评论5 views字数 4773阅读15分54秒阅读模式

前言

禅道是第一款国产的开源项目管理软件。它集产品管理、项目管理、质量管理、文档管理、 组织管理和事务管理于一体,是一款专业的研发项目管理软件,完整地覆盖了项目管理的核心流程。禅道项目管理系统覆盖了如下各行各业,其中也包含了行业的独角兽,流行范围广,命令执行漏洞的影响面也巨大。

禅道的前世今生-上
禅道的前世今生-上

故作此文,希望引起行业重视,积极配合修复漏洞,使用最新版禅道系统。

文章分两篇,上篇介绍如何绕过鉴权,进入禅道后台;下篇介绍禅道后台都有哪些可以深入利用的漏洞。

存在漏洞的版本

禅道开源版:[15.0,18.11]

禅道企业版:[5.0,8.11]

禅道旗舰版:[2.0,4.11]

以下分析均根据开源版。

看我如何进入禅道后台

1. 全域未鉴权漏洞

漏洞成因

鉴权错误未中止程序导致了未鉴权漏洞。

影响范围

[16.5-17.3]。

漏洞分析

先从这里开始了解禅道的鉴权逻辑吧。

禅道的前世今生-上

禅道的入口很简单,初始化禅道App后,解析参数,检查权限,检查Iframe,然后运行对应的模块和方法。

跟进checkPriv

禅道的前世今生-上

正常流程通过权限校验有两种。

  • 一个是不需要鉴权的模块和方法(白名单),对应isOpenMethod
  • 另一个则是正常登陆后,App记录了用户信息,即存在 $this->app->user变量。

但是图中可以看到,如果请求满足三点

  1. 请求不在白名单的方法
  2. 没有登录(没有$this->app->user)
  3. helper::isAjaxRequest() 返回False

会执行到helper::end(),抛出异常。

禅道的前世今生-上

然后异常被捕获,执行echo $endResponseException->getContent();,此时程序不会中止,继续向下执行,最后调用模块和方法。

登录了的用户的权限检查失败,会调用deny方法,也会执行到helper::end() 抛出异常。

禅道的前世今生-上

会产生如下两个问题:

  1. 未登录用户的未授权漏洞
  2. 登录用户的越权漏洞

至于16.5这个小版本呢,

https://github.com/easysoft/zentaopms/blob/zentaopms_16.5/module/common/model.php#L2235

禅道的前世今生-上

在没有登录用户时,直接响应print,也是一个未登录用户的未授权漏洞。

漏洞修复

https://github.com/easysoft/zentaopms/blob/zentaopms_17.4/module/common/model.php#L2382

将没有用户时,鉴权失败的 help::end() 改成了die

禅道的前世今生-上

但是!抛出异常还是echo哦,程序并没有退出。

2. 任意用户登录

漏洞成因

登录用户校验不完善导致黑客利用misc-captcha接口伪造SESSION和tutorial-wizard接口暴露用户密码,最终实现任意用户登录。

影响范围

[15.0,16.4]

[17.0-18.1)

漏洞分析

上面的漏洞仅影响当时的较新版禅道,影响范围小,还需要继续深入挖掘禅道的低版本的漏洞。

低版本禅道([15.0,16.4])鉴权方式如下

禅道的前世今生-上

没有登录直接die掉,也没有捕获任何异常。所以需要深入isOpenMethod ,看有哪些利用的白名单方法。

禅道的前世今生-上

我注意到这里的isLogon的校验并不严谨,仅判断有没有session->user,还有 user->account != 'guest' 。

禅道的前世今生-上

绕过的话,只需要找一个可以给session->user 设置值的地方即可,类型无所谓,php弱类型语言,当然这里能绕过,也归功于$this->session是一个对象类型,原理可以参照如下:

禅道的前世今生-上

虽然报错了,但仍然返回了true。

所以接下来挖掘的方向变成了 找到一个可以写入任意session的点,键可控或为user,值无关

写简单的正则即可:

  • this->session->set('user'
  • this->session->set($w*,

根据这两个正则表达式,可以找到两处可以写入用户的。

deny和  captcha

在15-17.x 版本中并未见到deny 方法的调用。

禅道的前世今生-上

captcha方法则是开放路由可访问的,接收sessionVar 参数,给session->$sessionVar 设置一个随机字符串。

禅道的前世今生-上

请求http://localhost:8082/index.php?m=misc&f=captcha&sessionVar=user

禅道的前世今生-上

成功写入session。但是仅有session,还没有用,因为低版本的禅道,鉴权失败会抛出异常的,异常并没有被捕获,所以程序中止。使用伪造的session一定会导致鉴权失败的,所以还需要再isOpenMethod方法中寻找出路。

我们现在已经通过了isLogon的校验了,可以执行下面的模块和方法了。

禅道的前世今生-上

在这些openMethod,找到 tutorial-wizard可以进一步利用。

禅道的前世今生-上

fetch 的逻辑简单来讲,就是后端内部调用接口,而非外部请求。外部请求需要校验权限,而fetch无需鉴权。

能调用的方法,需要满足以下条件

  1. 所属模块在 $this->lang->tutorial->tasks配置内
  2. GET请求

可以调用user 模块内的。

禅道的前世今生-上

user-todo方法

禅道的前世今生-上

允许接收一个userId,查询所有字段信息!

禅道的前世今生-上

也就是会把密码等字段查询出来,最后渲染整个User对象

禅道的前世今生-上

当渲染方式为JSON时, user对象的所有数据将会暴露,禅道会接受一个查询参数t。

禅道的前世今生-上

而且已知,禅道是对用户密码做了防护的。

禅道的前世今生-上

但此处没有,至今仍未修复。当然,有md5加密的密码,也可能存在无法解密的问题。

我在查看禅道的登录逻辑时,发现

禅道的前世今生-上

禅道是前端对密码进行md5加密,对应了后端密码长度位32的条件。

禅道的前世今生-上

也就是先对我们的明文密码md5,然后再拼接 rand,再次md5。

md5('21232f297a57a5a743894a0e4a801fc3'+'723913099') =  dac363f88d7b1b6459ee12e9fd4dd570 

所以,在知道verifyRand后,我们可以构造出请求包,直接使用数据库的md5密码就可以登录了后台。

漏洞修复

https://github.com/easysoft/zentaopms/blob/zentaopms_18.0/module/common/model.php

禅道在18.0的版本中修复了捕获异常不退出的漏洞。

也就是说在[17.0-18.0) 之间的版本,都存在利用misc-captcha 伪造session,然后捕获异常不退出的漏洞。

https://github.com/easysoft/zentaopms/blob/zentaopms_18.1/module/misc/control.php#L233

漏洞修复比较简单粗暴,直接禁止传入user

禅道的前世今生-上

但是治标不治本,上面的deny 依然可以创建session->user 。

https://github.com/easysoft/zentaopms/blob/zentaopms_18.1/module/user/model.php#L1203

禅道的前世今生-上

这里增加了 对$user->account 不为空的校验。

3. 任意用户修改(喧喧

漏洞成因

禅道集成喧喧,下载喧喧配置的接口未鉴权,禅道集成喧喧使用的密钥泄露,导致黑客可以伪造喧喧请求,修改用户密码。

影响版本

[15.3,18.7)

漏洞分析

下载喧喧配置的接口也是一个白名单接口

禅道的前世今生-上
禅道的前世今生-上
禅道的前世今生-上
禅道的前世今生-上

这个xuanxuan->key 是做什么的呢?

禅道框架的入口文件里,有一个x.php,这个文件是开放给喧喧使用的,使用了禅道框架里一个独立的App类,xuanxuan。

xuanxuan解析请求参数的方式入下,

禅道的前世今生-上

跟进setInput方法

禅道的前世今生-上

从数据库里查aesKey。

禅道的前世今生-上
禅道的前世今生-上

然后对请求进行解密。

所以我们可以下载xuanxuan配置,然后伪造xuanxuan请求x.php。

xuanxuan可以使用的方法也是一个白名单,基本只能访问im模块里的方法。

禅道的前世今生-上

这个模块就是专门给xuanxuan使用的,里面存在用户修改的方法。

禅道的前世今生-上

后面通过im模块里的模型类使用的__call魔术方法来控制方法调用的。

禅道的前世今生-上

user::update可以修改任意用户密码。

禅道的前世今生-上
禅道的前世今生-上

漏洞修复

在18.7版本中,修改了downloadXXD 方法。

https://github.com/easysoft/zentaopms/blob/zentaopms_18.7/xuanxuan/extension/xuan/setting/ext/control/downloadxxd.php#L6

禅道的前世今生-上

这个逻辑校验比较严格

  1. 存在登录用户,且存在该接口的权限
  2. 或者是管理员用户。

4. 任意用户创建/修改(API接口

漏洞成因

API接口处的登录用户校验不完善,和用户权限校验失败不退出的问题,导致黑客可以利用SESSION伪造问题,创建任意管理员用户或修改任意用户密码。

影响范围

[17.8-18.11]

漏洞分析

这个问题由来已久,直到现在才被修复,是与上面第二条的任意用户登录问题一并发现的。

回顾一下上面对于session伪造的修复

  1. misc-captcha禁止传入user值。
  2. isLogon方法增加了登录用户名的判断。

index.php 的入口点显然是被封堵了,继续寻找禅道的其他入口点。

禅道还提供了api.php 用来调用API,也用了一个独立的App类,下面叫他api应用。

禅道的前世今生-上

api应用,在创建时,会截取入口文件后的第一个路径参数,作为版本。

禅道的前世今生-上

如果存在版本变量,就不调用 $common->checkPriv() 。

checkPriv与index.php 的主入口一样,此处不再介绍。

看一下checkEntry,与checkPriv 一样也是鉴权的。

禅道的前世今生-上

如果存在版本号,则直接返回checkNewEntry()的执行结果。否则先检查是否是白名单方法,如果不在白名单里,就从数据库中查询Token,查不到,或者Token不对则返回错误。

禅道的前世今生-上

跟进一下checkNewEntry方法。

禅道的前世今生-上

注意这里是return ! 只是退出了当前函数,而不是鉴权失败中止程序继续执行

所以在请求时加上一个对应版本的路径参数,即可绕过,或者换句话说,api.php入口的鉴权也是失效的。

禅道的API接口定义如下。

禅道的前世今生-上

路由到的类文件结构如下。

禅道的前世今生-上

每个文件代表一个模块的实体类,继承于Entry父类,类中的方法对应了HTTP的请求方法。

禅道的前世今生-上

在父类的构造函数里,禅道做了登录用户的校验。

禅道的前世今生-上

跟第二个漏洞中登录用户校验一样的配方,一样的味道,一样可以用SESSION伪造来绕过。

至于SESSION伪造的方式,在修复了user-captcha后,还可以使用 deny方法。

禅道18.1版本后,上线了一个白名单方法。

禅道的前世今生-上

然后刚好就调用了deny方法。

禅道的前世今生-上

这一切刚刚好好,天造地设,无缝衔接。

至此,我们可以通过伪造SESSION,然后访问禅道的API接口。

但是禅道模块的API实体类,实际上是获取了对应模块的控制器类。

比如获取用户的API方法里,

禅道的前世今生-上

在加载控制器时,又检查了一次权限的。

禅道的前世今生-上

校验失败,返回403。

禅道的前世今生-上

send方法在低于17.8的版本里是直接退出了。

禅道的前世今生-上

高于17.8的版本则直接输出未授权,但是程序继续执行不退出

禅道的前世今生-上

所以,在高于17.7的版本里,是可以直接未授权访问禅道接口的。禅道接口里 PUT /users/:id 可以修改用户密码,POST /users/  可以创建任意管理员账户。

漏洞修复

在18.12里,禅道做了很多细节上的改动。

  1. 修复了实体类构造函数里的鉴权不严谨
禅道的前世今生-上
  1. 实体类的checkPriv权限校验失败直接退出
禅道的前世今生-上
  1. 直接移除了checkNewEntry
禅道的前世今生-上

对于此漏洞修复得很完善了。

后记

下篇我将对禅道后台各个版本的高危漏洞进行深入分析,请关注公众号。

如果对分析有任何疑问,欢迎留言讨论。

原文始发于微信公众号(天命团队):禅道的前世今生-上

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年1月9日15:30:41
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   禅道的前世今生-上https://cn-sec.com/archives/3605187.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息