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

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

缺陷编号:wooyun-2015-0148148

漏洞标题:iwebshop某处设计缺陷导致大面积注入

相关厂商:www.jooyea.cn

漏洞作者: Xser

提交时间:2015-10-27 17:25

修复时间:2015-12-17 14:48

公开时间:2015-12-17 14:48

漏洞类型:SQL注射漏洞

危害等级:高

自评Rank:20

漏洞状态:厂商已经确认

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

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2015-10-27: 细节已通知厂商并且等待厂商处理中
2015-10-31: 厂商已经确认,细节仅向厂商公开
2015-11-03: 细节向第三方安全合作伙伴开放(绿盟科技唐朝安全巡航
2015-12-25: 细节向核心白帽子及相关领域专家公开
2016-01-04: 细节向普通白帽子公开
2016-01-14: 细节向实习白帽子公开
2015-12-17: 细节向公众公开

简要描述:

iwebshop_v4.1.15091900最新版
某个函数写的不规范

详细说明:

出现在sql处理函数上
看到iwebshop4.1/lib/web/model/model_class.php

/**
* @brief 更新
* @param string $where 更新条件
* @param array $except 非普通数据形式(key值)
* @return int or bool int:影响的条数; bool:false错误
*/
public function update($where,$except=array())
{
$except = is_array($except) ? $except : array($except);
//获取更新数据
$tableObj = $this->tableData;
$updateStr = '';
$where = (strtolower($where) == 'all') ? '' : ' WHERE '.$where;
foreach($tableObj as $key => $val)
{
if($updateStr != '') $updateStr.=' , ';
if(!in_array($key,$except))
$updateStr.= '`'.$key.'` = \''.$val.'\'';
else
$updateStr.= '`'.$key.'` = '.$val;
}
$sql = 'UPDATE '.$this->tableName.' SET '.$updateStr.$where;
return $this->db->query($sql);
}


$where     = (strtolower($where) == 'all') ? '' : ' WHERE '.$where;


看到这里只是把值转小写然后=='all' php是弱类型所以 xxxxx和all用==比较的值是一样为1的,所以值就为' WHERE '.$where;可以看到没有单引号包含
最后拼接sql语句然后带入查询

$sql = 'UPDATE '.$this->tableName.' SET '.$updateStr.$where;
return $this->db->query($sql);


原因出现在这里

if(!in_array($key,$except))
$updateStr.= '`'.$key.'` = \''.$val.'\'';
else
$updateStr.= '`'.$key.'` = '.$val;
}


存在数组里就$updateStr.= '`'.$key.'` = '.$val; 所以没有单引号包含
我们来搜索下有哪里调用了

360截图20151020192907667.jpg


数量还挺多的
选了一处来测试
/controllers/member.php

public function ajax_seller_lock()
{
$id = IFilter::act(IReq::get('id'));
$lock = IFilter::act(IReq::get('lock'));
$sellerObj = new IModel('seller');
$sellerObj->setData(array('is_lock' => $lock));
$sellerObj->update("id = ".$id);
//短信通知状态修改
$sellerRow = $sellerObj->getObj('id = '.$id);
if(isset($sellerRow['mobile']) && $sellerRow['mobile'])
{
$result = $lock == 0 ? "正常" : "锁定";
$content = smsTemplate::sellerCheck(array('{result}' => $result));
$result = Hsms::send($sellerRow['mobile'],$content);
}
}


$id = IFilter::act(IReq::get('id'));这里没有过滤转换类型就传入了
$sellerObj->update("id = ".$id);最后带入了查询

360截图20151020193255756.jpg


可以看到带入sql语句了

360截图20151020193309479.jpg


而且没有单引号也不用担心gpc

漏洞证明:

出现在sql处理函数上
看到iwebshop4.1/lib/web/model/model_class.php

/**
* @brief 更新
* @param string $where 更新条件
* @param array $except 非普通数据形式(key值)
* @return int or bool int:影响的条数; bool:false错误
*/
public function update($where,$except=array())
{
$except = is_array($except) ? $except : array($except);
//获取更新数据
$tableObj = $this->tableData;
$updateStr = '';
$where = (strtolower($where) == 'all') ? '' : ' WHERE '.$where;
foreach($tableObj as $key => $val)
{
if($updateStr != '') $updateStr.=' , ';
if(!in_array($key,$except))
$updateStr.= '`'.$key.'` = \''.$val.'\'';
else
$updateStr.= '`'.$key.'` = '.$val;
}
$sql = 'UPDATE '.$this->tableName.' SET '.$updateStr.$where;
return $this->db->query($sql);
}


$where     = (strtolower($where) == 'all') ? '' : ' WHERE '.$where;


看到这里只是把值转小写然后=='all' php是弱类型所以 xxxxx和all用==比较的值是一样为1的,所以值就为' WHERE '.$where;可以看到没有单引号包含
最后拼接sql语句然后带入查询

$sql = 'UPDATE '.$this->tableName.' SET '.$updateStr.$where;
return $this->db->query($sql);


原因出现在这里

if(!in_array($key,$except))
$updateStr.= '`'.$key.'` = \''.$val.'\'';
else
$updateStr.= '`'.$key.'` = '.$val;
}


存在数组里就$updateStr.= '`'.$key.'` = '.$val; 所以没有单引号包含
我们来搜索下有哪里调用了

360截图20151020192907667.jpg


数量还挺多的
选了一处来测试
/controllers/member.php

public function ajax_seller_lock()
{
$id = IFilter::act(IReq::get('id'));
$lock = IFilter::act(IReq::get('lock'));
$sellerObj = new IModel('seller');
$sellerObj->setData(array('is_lock' => $lock));
$sellerObj->update("id = ".$id);
//短信通知状态修改
$sellerRow = $sellerObj->getObj('id = '.$id);
if(isset($sellerRow['mobile']) && $sellerRow['mobile'])
{
$result = $lock == 0 ? "正常" : "锁定";
$content = smsTemplate::sellerCheck(array('{result}' => $result));
$result = Hsms::send($sellerRow['mobile'],$content);
}
}


$id = IFilter::act(IReq::get('id'));这里没有过滤转换类型就传入了
$sellerObj->update("id = ".$id);最后带入了查询

360截图20151020193255756.jpg


可以看到带入sql语句了

360截图20151020193309479.jpg


而且没有单引号也不用担心gpc

修复方案:

public function update($where,$except=array())
{
$except = is_array($except) ? $except : array($except);
//获取更新数据
$tableObj = $this->tableData;
$updateStr = '';
$where = (strtolower($where) == 'all') ? '' : ' WHERE '.$where;
foreach($tableObj as $key => $val)
{
if($updateStr != '') $updateStr.=' , ';
if(!in_array($key,$except))
$updateStr.= '`'.$key.'` = \''.$val.'\'';
else
$updateStr.= '`'.$key.'` = \''.$val.'\'';
}
$sql = 'UPDATE '.$this->tableName.' SET '.$updateStr.$where;
return $this->db->query($sql);
}

应该这样写

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


漏洞回应

厂商回应:

危害等级:低

漏洞Rank:3

确认时间:2015-10-31 21:35

厂商回复:

1,处理思路不应该从IModel的update value强制加引号,这样会导致部分mysql函数的值无法写入,比如: update iwebshop_goods set time=NOW(); 如果按照写入值强制引号的思路,那么sql就变成了: update iwebshop_goods set time="NOW()"; 解决的方式还是应该在IReq::get('参数'); 通过不同的数据类型进行不同的转换。
2,测试报告里面的用例都是后台专用的控制器和方法,必须具有管理员的权限,意义不是很大。

最新状态:

暂无