禅道linux一键安装漏洞,禅道远程代码执行漏洞复现分析

1.   前言

2019年9月,禅道项目管理软件爆出全版本的RCE漏洞。于是便好奇漏洞的成因,在阅读作者的文章及自己复现分析后,发现漏洞其实算是一种越权调用,普通权限(用户组为1-10)的攻击者可通过module/api/control.php中getModel方法,越权调用module目录下所有的model模块和方法,从而实现SQL注入、任意文件读取、远程代码执行等攻击。

2.   漏洞分析

在分析漏洞之前,先需要了解禅道的路由模式。禅道有两种路由模式PATH_INFO(2)、GET方式,其中GET方式为常见的m=module&f=method形式传递模块和方法名,而PATH_INFO(2)则是通过路径和分隔符的方式传递模块和方法名。路由方式及分隔符定义在config/config.php中,下载的禅道11.6.1默认使用PATH_INFO路由方式。

e5e1d55a5088296111d488b468780889.png

接下来,从入口文件www/index.php开始分析禅道如何传参的,在index.php的66-68行,调用了三个方法parseRquest()、checkPriv()、loadModule()。

4cdcf16c6c73a0e19a614217d9dd1b69.png

先跟进framework/base/router.class.php查看parseRquest方法,当路由方式为PATH_INFO或者PATH_INFO2的时候,会调用setRouteByPathInfo方法,将$this->URI用”-”分割,第一个参数设置为模块名,第二个参数设置为方法名,检查是否存在后传递到baseRouter类的变量中。

1363eb1b1506c1bac044f1ff07c747b1.png

再跟进module/common/model.php checkPriv方法,主要是验证将要调用的模块和方法对当前用户是否有权限,除了isOpenMethod中定义的公开模块和方法之外,其他的方法都是需要登录的。

f9a6fe04abd05e5053ab14e5a0713f91.png

而本漏洞需要利用的模块和方法分别为api、getModel,可以zt_grouppriv表中查询调用该接口所需要的权限组为1-10,这意味着普通用户即可以调用该接口。

0c586a198ab28c2f06722cc4aa089ffb.png

17ffb69bcf3f689bda8b3011568b61d9.png

最后到load_Module方法,通过之前获取的moduleName包含对应的control类文件并实例化,随后调用setParamsByPathInfo方法从路径中获取方法对应的参数值,最后通过call_user_func_array方法调用对应control类中的对应方法并赋值。

5438c41b7734f714ade3b99282cdd928.png

6f9754adcee0901bfac87f1b5276e426.png

存在漏洞接口为module/api/control.php的getModel方法,这是一个能够调用所有model类的超级方法,51行loadModel方法能否调用指定指定模块的model文件并返回model对象。配合52行的call_user_func_array函数便可以调用所有的model文件的所有方法。

d1e6fb43456c3a44eaee47c70da413b2.png

3.   漏洞利用

原作者利用的是文件写入和文件包含结合执行任意代码,这里有一个更加简单的方式可以直接写入webshell。文件写入漏洞代码位于module/editor/model.php中的save方法,$filePath和$fileContent都可以控制。

e92813db3803cacd24a61622c571b7b2.png

要想写入php文件这里需要可以在路径中引入”.”,这里先看禅道会对PATH中传递的参数名和参数值限制规则config/filter.php,对参数值的正则为^[a-zA-Z0-9=_,`#+\^\/\.%\|\x7f-\xff]+$,这里其实是可以有”.”的。

9c5f3f7a5b66b3d20fa564e215e644db.png

但是为什么原作者放弃了直接写入webshell的方法呢,真实原因在framework/base/router.class.php的parsePathInfo方法,程序会先匹配路径中是否有”.”,如果有的话,将第一个点之前的部分作为需要解析的路径,之后的部分作为视图类型。这就解释了之前漏洞作者为什么没能直接写入webshell。

cd3651391f38e03cbdfd788c6e149393.png

那么如何绕过呢,仔细分析程序发现在module/api/control.php的getModel方法中调用了parse_str对参数进行处理,而parse_str会对参数值做一次url解码!那么问题迎刃而解了,可以对”.”以及其他被限制的字符做两次url编码,即可以绕过对字符串中”.”的分割以及之后正则的匹配。直接写入webshell的请求如下:

f5d665074092e544dffac1639dc4555b.png

由于路由的原因,必须覆盖www目录下的原有php文件才可以被直接解析,这里可以覆盖x.php。

c22ba2bed9681d41a45179438c490dfd.png

4.   参考链接

本文由百度安全原创,转载请标注来源及原文链接

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值