SQL注入常規Fuzz全記錄
前言
本篇文章是在做ctf bugku的一道sql 盲注的題(題目地址: ofollow,noindex" target="_blank">注入題目 )中運用了fuzz的思路,完整記錄整個fuzz的過程,給師傅們當點心,方便大家加深對web sql注入 fuzz的理解。
進入主題
1.訪問題目,是個典型的登入框
2.嘗試輸入admin/123456,提示密碼錯誤,因此可以確定存在使用者admin,這裡可能會有師傅要爆破了,但這裡題目要求sql注入,我們就按照預期解來吧。
3.我自己寫了個簡單的fuzz burp外掛,先將登陸請求包傳送到外掛掃描,可以看到是存在盲注的,payload的形式為:
4.fuzz
(1)從payload的形式可以猜測題目應該是過濾了註釋符(–+和#)
(2)fuzz一遍特殊字元,看看過濾了什麼
當存在過濾的字元時,響應包是這樣的
因此可以作為fuzz的判斷(當然有些waf是靜默waf,就是照樣接收你的資料但自己做了處理,返回正常頁面,這種fuzz的判斷有時候就需要設計下你的payload,這種在以後的文章繼續討論)
fuzz特殊字元,結果如下,可以看到長度為370的是被wa了的,過濾了相當多的字元,特別是內聯註釋 註釋符 空格 %0a %0b %0d %a0這些比較常用的繞過關鍵元件,尤其注意過濾了逗號
(3)fuzz一遍關鍵字,過濾了and or order union for 等等,因此取資料常用的mid( xx from xx for xx)就不能用了,之前逗號也被過濾了也就不能用mid(xx,1,1)。
(4)fuzz函式名和操作符(由於外掛的掃描結果沒有過濾sleep,直覺上是沒有對函式做過濾)
不出意外,確實是只有包含關鍵字or and等的函式被wa了,其他基本沒有,其實這裡我們也可以聯想到跑表經常要用的information_schema表是存在or關鍵字的,因此後面構造語句的時候也就不能直接用information_schema
(5)嘗試用時間盲注跑資料
if(1=1,sleep(5),0)
由於不能用逗號需要變為
CASE WHEN (1=1) THEN (sleep(5)) ELSE (2) END
但空格也被過濾了,需要用括號代替空格(/*!*/ 空格 tab %a0 %0d%0a均被過濾了)
(CASE WHEN(1=1)THEN(sleep(1))ELSE(1)END);
最後本地測試的時候發現case when之間不能用括號,做一下字元fuzz,從%00到%ff
可以看到結果是確實不行,並不能產生延時(有的直接被wa,有的沒被wa但sql語句無法生效),因此基本可以確認不能用時間盲注跑資料,於是我們只能考慮布林盲注
(6)嘗試布林盲注
由於無法使用if或者case/when,只能使用題目自帶的bool盲注做邏輯判斷(=) 比如我們一開始就注意到存在admin使用者,改造外掛的payload: ‘+sleep(5)+’ (注意把+換為%2b)
admin'+1+' (false,注意把+換為%2b) admin'+0+' (true,注意把+換為%2b)
select * from user where name='admin'+1+'' and passwd='123456';(為false) ==>提示使用者名稱錯誤 select * from user where name='admin'+0+'' and passwd='123456';(為true) ==>提示密碼錯誤
這裡是mysql的一個特性,可能有不明白的師傅,可以做下實驗
select 'admin'='admin'+0 union select 'admin'='admin'+1;
前者為1後者為0,先對右邊的等式做運算,發生強制轉換,結果為數字,然後再和左邊的admin字元做比較,又發生了強制轉換,因此出現1和0的區別。
這樣子我們就解決了布林盲注的判斷了
(7)解決下跑資料的問題
這裡不能用mid(xxx,1,1)也不能用mid(xxx from 1 for 1),但查手冊發現可以使用mid(xxx from 1),表示從第一位開始取剩下的所有字元,取ascii函式的時候會發生截斷,因此利用ascii(mid(xxx from 1))可以取第一位的ascii碼,ascii(mid(xxx from 2))可以取第二位的ascii,依次類推
(8)burp跑資料
a.判斷passwd欄位的長度: 跑出長度為32
(這裡可以猜欄位,根據post請求包中的passwd猜測資料庫的欄位應該也是passwd,這樣就可以不用去跑information_schema,直接在登陸查詢語句中獲取passwd)
admin'-(length(passwd)=48)-'
b.跑第一位
這裡的payload我用的不是上面的,從最後面開始倒著取資料然後再reverse一下,那時候做題沒轉過彎,其實都一樣的,用下面的payload的好處是假如ascii不支援截斷的情況下是不會報錯的(用於其他資料庫的時候)
=admin'-(ascii(mid(REVERSE(MID((passwd)from(-1)))from(-1)))=48)-'
用這一個也可以的
=admin'-(ascii(mid(passwd)from(1))=48)-'
重複上述操作修改偏移,即可獲取32位密碼005b81fd960f61505237dbb7a3202910解碼得到admin123,登陸即可獲取flag,到這裡解題過程結束。
總結
1.上述用到的fuzz字典均可在sqlmap的字典以及mysql官方手冊中收集
2.這裡僅僅是常規的fuzz,但大多數fuzz其實都是相通的,主要是fuzz的判斷,fuzz的位置,fuzz payload的構造技巧等等
3.歡迎各位大師傅一起交流討論!
*本文作者:Conan,轉載請註明來自FreeBuf.COM