漏洞概述
禅道是第一款国产的开源项目管理软件,也是国内最流行的项目管理软件。该系统在2023年初被爆出在野命令执行漏洞,官方已于2023年1月12日发布了漏洞修复补丁。该漏洞是由于禅道项目管理系统权限认证存在缺陷导致,攻击者可利用该漏洞在未授权的情况下,通过权限绕过在服务器执行任意命令。
本文以安全研究为目的,分享对该漏洞的研究和复现过程,仅供学习和参考。由于传播、利用此文档提供的信息而造成任何直接或间接的后果及损害,均由使用者本人负责,文章作者不为此承担任何责任。
影响范围
禅道系统 |
影响版本 |
开源版 |
17.4以下的未知版本<=version<=18.0.beta1 |
旗舰版 |
3.4以下的未知版本<=version<=4.0.beta1 |
企业版 |
7.4以下的未知版本<=version<=8.0.beta1 8.0.beta2 |
复现环境
操作系统:macOS 13.1
运行环境:nginx1.5 php7.4 mysql5.7
软件版本:zentaopms-zentaopms_18.0.beta1
权限绕过-漏洞分析
权限绕过的关键点在module/common/model.php文件中checkPriv函数,此函数是检查权限的函数,验证当前登陆用户是否有访问module与method的权限。分析代码后得知在没有访问权限时会抛出异常,但是代码中并没有终止程序,只是输出权限不足的内容。具体代码如下:
1 |
<code><span style="padding:0px; max-width:1000%;"> <span style="padding:0px; max-width:1000%;"><span style="padding:0px; max-width:1000%; color:rgb(202, 125, 55);">public</span> function <span style="padding:0px; max-width:1000%; color:rgb(221, 17, 68);">checkPriv</span><span style="padding:0px; max-width:1000%;">()</span></span></span></code><code><span style="padding:0px; max-width:1000%;">{</span></code><code><span style="padding:0px; max-width:1000%;"> <br> <span style="padding:0px; max-width:1000%; color:rgb(202, 125, 55);">try</span></span></code><code><span style="padding:0px; max-width:1000%;"> <br> {</span></code><code><span style="padding:0px; max-width:1000%;"> <br> $<span style="padding:0px; max-width:1000%; color:rgb(202, 125, 55);">module</span> = $<span style="padding:0px; max-width:1000%; color:rgb(202, 125, 55);">this</span>->app->getModuleName();</span></code><code><span style="padding:0px; max-width:1000%;"> <br> $method = $<span style="padding:0px; max-width:1000%; color:rgb(202, 125, 55);">this</span>->app->getMethodName();</span></code><code><span style="padding:0px; max-width:1000%;"> <br> <span style="padding:0px; max-width:1000%; color:rgb(202, 125, 55);">if</span>($<span style="padding:0px; max-width:1000%; color:rgb(202, 125, 55);">this</span>->app->isFlow)</span></code><code><span style="padding:0px; max-width:1000%;"> <br> {</span></code><code><span style="padding:0px; max-width:1000%;"> <br> $<span style="padding:0px; max-width:1000%; color:rgb(202, 125, 55);">module</span> = $<span style="padding:0px; max-width:1000%; color:rgb(202, 125, 55);">this</span>->app->rawModule;</span></code><code><span style="padding:0px; max-width:1000%;"> <br> $method = $<span style="padding:0px; max-width:1000%; color:rgb(202, 125, 55);">this</span>->app->rawMethod;</span></code><code><span style="padding:0px; max-width:1000%;"> <br> }</span></code><code><span style="padding:0px; max-width:1000%;"><br></span></code><code><span style="padding:0px; max-width:1000%;"> $beforeValidMethods = <span style="padding:0px; max-width:1000%; color:rgb(202, 125, 55);">array</span>(</span></code><code><span style="padding:0px; max-width:1000%;"> <br> <span style="padding:0px; max-width:1000%; color:rgb(221, 17, 68);">'user'</span> => <span style="padding:0px; max-width:1000%; color:rgb(202, 125, 55);">array</span>(<span style="padding:0px; max-width:1000%; color:rgb(221, 17, 68);">'deny'</span>, <span style="padding:0px; max-width:1000%; color:rgb(221, 17, 68);">'logout'</span>),</span></code><code><span style="padding:0px; max-width:1000%;"> <br> <span style="padding:0px; max-width:1000%; color:rgb(221, 17, 68);">'my'</span> => <span style="padding:0px; max-width:1000%; color:rgb(202, 125, 55);">array</span>(<span style="padding:0px; max-width:1000%; color:rgb(221, 17, 68);">'changepassword'</span>),</span></code><code><span style="padding:0px; max-width:1000%;"> <br> <span style="padding:0px; max-width:1000%; color:rgb(221, 17, 68);">'message'</span> => <span style="padding:0px; max-width:1000%; color:rgb(202, 125, 55);">array</span>(<span style="padding:0px; max-width:1000%; color:rgb(221, 17, 68);">'ajaxgetmessage'</span>),</span></code><code><span style="padding:0px; max-width:1000%;"> <br> );</span></code><code><span style="padding:0px; max-width:1000%;"> <br> <span style="padding:0px; max-width:1000%; color:rgb(202, 125, 55);">if</span>(!empty($<span style="padding:0px; max-width:1000%; color:rgb(202, 125, 55);">this</span>->app->user->modifyPassword) <span style="padding:0px; max-width:1000%; color:rgb(202, 125, 55);">and</span> (!isset($beforeValidMethods[$<span style="padding:0px; max-width:1000%; color:rgb(202, 125, 55);">module</span>]) <span style="padding:0px; max-width:1000%; color:rgb(202, 125, 55);">or</span> !in_array($method, $beforeValidMethods[$<span style="padding:0px; max-width:1000%; color:rgb(202, 125, 55);">module</span>]))) <span style="padding:0px; max-width:1000%; color:rgb(202, 125, 55);">return</span> print(js::locate(helper::createLink(<span style="padding:0px; max-width:1000%; color:rgb(221, 17, 68);">'my'</span>, <span style="padding:0px; max-width:1000%; color:rgb(221, 17, 68);">'changepassword'</span>)));</span></code><code><span style="padding:0px; max-width:1000%;"> <br> <span style="padding:0px; max-width:1000%; color:rgb(202, 125, 55);">if</span>($<span style="padding:0px; max-width:1000%; color:rgb(202, 125, 55);">this</span>->isOpenMethod($<span style="padding:0px; max-width:1000%; color:rgb(202, 125, 55);">module</span>, $method)) <span style="padding:0px; max-wi |

文章详细介绍了禅道项目管理软件中存在的权限绕过漏洞,该漏洞允许未授权的攻击者在系统中执行任意命令。漏洞源于权限认证函数checkPriv存在缺陷,通过构造特定的session可以绕过权限检查。此外,文中还提到了一个命令执行漏洞,涉及module/repo/model.php文件中的checkConnection函数,攻击者可以通过设置SCM为Subversion来执行命令。官方已在2023年1月12日发布了修复补丁,建议受影响用户尽快升级以确保系统安全。
最低0.47元/天 解锁文章
1090

被折叠的 条评论
为什么被折叠?



