4-Web安全——SQL盲注

目錄

1. SQL盲注

2. 布爾盲注

3. 時間盲注

4. 總結


 

 

1. SQL盲注

在進行SQL注入過程中,如果當前頁面沒有報錯回顯,無法獲取數據庫返回結果的情況下,可以使用SQL盲注的方式對數據庫中的內容進行猜解,盲注類型主要分爲:布爾盲注和時間盲注。

當web頁面只返回真假(true或false)兩種不同類型的結果情況下,利用頁面返回的不同類型結果逐個猜解數據就可以使用布爾盲注,如果web頁面不返回true或false類型的結果,則可以使用時間注入。

 

真實的注入環境中,web頁面肯定不會直接回顯true或false的,一般根據頁面返回的結果作爲依據來判斷。

 

2. 布爾盲注

例如:?id=1' and 1=1 --+ ,測試結果如下:

如果當前頁面返回了結果,說明布爾盲注的條件爲真(true)。

 

 

反之,布爾盲注的條件爲假(false):

 

 

通常數據庫正確執行SQL語句時,web頁面並不會返回信息到頁面:

在這條SQL語句中 ?id=1' union select 1,database(),3--+ ,數據庫在執行SQL語句時查詢數據庫名,但web頁面並不會直接返回數據庫名字,因此可以通過布爾盲注使用ascii函數的方式,以SQL執行後返回到web頁面的結果來判斷要查詢的內容對應的ascii碼是否正確。

 

ascii()函數:ascii碼是美國信息交換標準代碼,可以將字母轉換爲對應的數字形式的ascii碼。

 

select ascii('a');語句的作用就是將字母a轉換爲對應的ascii碼,也就是97。

 

 

例如,構造SQL語句:?id=1' and ascii('a') ==97--+  ,頁面返回結果:

 

 

構造SQL語句:?id=1' and ascii('a') ==99--+  ,頁面返回結果:

很明顯,字母a的ascii碼不是99,因此數據庫執行SQL語句的結果是false,頁面不回顯任何結果。

 

 

由於頁面是不回顯命令查詢的結果,當我們想要獲取當前使用的數據庫時,select ascii(select database())每次只能顯示一個字母對應的數字,可使用substring函數來實現截取字母:

select ascii(substring((select database()),1,1));

substring函數主要是用於截取字符串的,有三個參數,第一個參數是要截取的字符串,第二個參數是截取字符的起始位置,第三個參數是截取字符的個數。

 

獲取數據庫名字時,通過substring函數和大於號和小於號來猜解字母的ascii碼,字母‘a’到‘z’的ascii碼值的範圍是97 - 122,利用二分法的原則來對查找的數據庫名字進行猜解。英文字母的區間範圍是97 - 122,去中值就是112,在之後的字符猜解過程中,我們每次可以使用二分法取中值進行猜解:

 

第一次猜解:

Web頁面返回true,說明第一個字符的ascii碼值是大於112的。

 

 

再次對112到122之間取中值,進行第二次猜解:

我們發現第一個字符是不大於115的,那麼我們猜測第一個字符是等於或小於115。

 

 

第三次猜解:

頁面返回了true,說明第一個字符的ascii碼值就是115,而115對應的字母就是字符‘s’,剩下的字符以此類推,修改substring函數的參數然後用二分法猜解出數據庫的名字。

 

 

在真正的注入過程中,構造SQL語句如下:

#limit 0,1表示從第0行開始顯示一行數據
?id=1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))>100--+

 

 

 

3. 時間盲注

布爾盲注通過web頁面返回真假(true或false)兩種不同類型的結果來進行判斷,拿到想要的信息。但有時候web頁面可能只返回一個正常的頁面,沒有其他的錯誤信息可以反饋。

 

時間盲注就是web頁面只返回一個正常頁面,利用頁面響應時間不同,逐個猜解數據,使用場景一般是數據庫會正常執行命令,不反饋頁面信息。

 

舉個例子:

在這個示例中無論如何構造SQL語句,web頁面始終只返回一個正常的頁面,這種情況一般是無法單獨通過布爾注入進行判斷,還需要使用到時間盲注方式。

 

時間盲注主要使用到兩個函數,sleep函數和if函數。

 

sleep函數顧名思義,就是休眠的意思,參數以秒爲單位,也可以爲小數,使用方式如下所示:

 sleep函數的參數可以爲整數,也可以爲小數,sleep(3.14)表示數據庫執行命令查詢到結果後,會休眠3.14秒再返回結果。

 

if函數,學過編程語言的同學肯定知道if在編程語言中是一個條件判斷語句,有三個參數:

if(condition , true , false)
  1. condition參數表示if語句判斷的條件
  2. true參數表示當condition條件爲真時返回的值
  3. false參數則表示condition條件爲假時返回的值

 

 

再來舉個栗子:

分析:if(1=1,sleep(3),sleep(0))SQL語句,條件1=1的結果爲真,接着就執行sleep(3)動作,休眠3秒後再返回結果。如果把條件修改爲1=2,則條件1=2爲假,執行sleep(0)動作,休眠0秒返回結果。

 

還記得SQLi-LABS的第9關嗎,無論如何構造SQL語句頁面都沒有反饋信息,更無法判斷出當前web頁面的注入類型和閉合方式,那麼我們可以採用布爾注入加時間注入方式了:

構造的命令是?id=1' and sleep(2)--+,從頁面的執行結果來看,確實等待了2秒才把結果返回,也就是說and關鍵字後面的sleep(2)語句確實是被執行了,由此我們可以確定當前頁面的注入方式了。

 

布爾注入加時間注入,構造SQL語句:

select if((ascii(substr((select database()),1,1))>112),sleep(3),sleep(0));

if語句中的條件爲(ascii(substr((select database()),1,1))>112),當條件爲真時,數據庫執行命令查詢到結果後,會等待3秒再返回結果,利用布爾注入中的二分法可以猜解出第一個字符是s,以此類推,按照這種方式就可以獲取到完整的數據庫名字,表名等信息。

 

 

4. 總結

 

SQL盲注小結:

布爾盲注是在web頁面只返回真假(true或false)兩種不同類型的結果進行判斷,從而猜解出想要的信息。時間盲注是通過web頁面執行數據庫命令的時長來猜解出想要的信息,兩種注入方式原理是相通的,但也各有優缺點,在真實的注入環境中通常兩種注入方式相互配合靈活使用。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章