如何繞過WAF

目錄php

HTTP報文包體的解析html

Transfer-Encodingnginx

Charsetgit

溢量數據程序員

HTTP協議兼容性github

HTTP請求行種的空格web

HTTP 0.9+Pipeliningsql

Websocket、HTTP/2.0json

高層數據tomcat

base64

Unicode JSON

實體編碼 XML

八進制

同形字

容器語言特性

匹配緩衝區大小固定

白名單

輸出角度

OOB

Range

其餘參考

傳輸層

SSL層

DOS

結語


本文主要從繞過WAF過程當中須要注意的角色和點出發,嘗試理解它們的運做,構建一個簡單的知識框架。

首先,WAF分爲非嵌入型WAF和嵌入型WAF,非嵌入型WAF指的是硬WAF、雲WAF、虛擬機WAF之類的;而嵌入型WAF指的是Web容器模塊類型的WAF、代碼層WAF。非嵌入型WAF對Web流量的解析徹底是靠自身的,而嵌入型WAF拿到的Web數據是已經被解析加工好的。因此非嵌入型的受攻擊機面還涉及到其餘層面,而嵌入型WAF從Web容器模塊類型WAF、代碼層WAF往下走,其對抗畸形報文、掃操做繞過的能力愈來愈強。固然,在部署維護成本方面,也是越高的。

有些WAF設置的是針對域名的防禦,有些時候,咱們嘗試將域名改爲ip地址能夠繞過WAF的防禦。

HTTP報文包體的解析

咱們先來探討一個問題。HTTP請求的服務器在接收到該請求時,會關心哪些頭部字段,以及如何根據這些頭部字段作出對Request-body 進行相應的解析處理。說實話,要搞清這些東西,最好仍是查看web容器的源碼,但筆者如今還沒作到這一步,在這裏僅能根據自身的認知說起一些頭部字段。這些頭部字段的關係,筆者認爲能夠總結爲以下:

Transfer-Encoding(Content-Encoding(Content-Type(charset(data))))

Transfer-Encoding

關於Transfer-Encoding,傳送門——>數據的分段編碼(transfer-encoding) 

Apache+php對chunked類型的HTTP請求的處理太怪了。RFC2616中說明了,客戶端或服務器,收到的HTTP報文中,若是同時存在chunked與Content-Length,則必定要忽略掉content-length,而在Apache中卻不能缺乏。理由是Apache自己是不支持解析chunked的(對於Apache來講,因爲沒有解析HTTP請求chunked的代碼邏輯,因此必定要從content-length中查看該報文的長度,而chunked多是被PHP解析了的,因此這兩個頭部必定要同時存在)。這一結論也很好地解釋了一些不解的現象,如利用chuncked編碼能夠繞過安全狗Apache。 經過shodan搜索相關服務器,簡單測試一下,關於常見中間件、語言與chuncked的關係有以下參考:

  ASPX PHP Java
Apache X Y  
Nginx Y   Y
IIS Y Y  
Tomcat     X

那關於chunked,能夠有什麼利用思路呢? 思路一,構造一個chunked請求體,嘗試繞過WAF。其中能夠涉及到利用chunked自己的一些規範、特性。 好比,假如WAF會解析chunked,但加入一些chunked的擴展,WAF就解析不了。 反過來,腦洞一下,假如WAF意識到了解析chunked時應該忽略這些擴展,那麼在Tomcat下咱們是否是能夠利用它一下。

相關文章:利用分塊傳輸吊打全部WAF

                  在HTTP協議層面繞過WAF

                  HTTP 協議中的 Transfer-Encoding

Content-Type

Web容器應該不怎麼關心Content-Type這個字段,後臺語言會識別該字段並進行對應的數據解析。而咱們利用該字段的話,主要從如下思路出發:後臺語言會識別哪些類型的Content-Type,這些Content-Type對咱們繞WAF有沒有用。 PHP默認會處理application/x-www-form-urlencoded、multipart/form-data兩種。而JAVA後臺對於multipart/form-data類型Content-Type的識別處理,須要藉助三方庫或是框架,默認狀況下是沒法處理的,但如今通常都用框架,而框架可能默認狀況下就會識別並處理這類型的請求。 後臺接收到application/x-www-form-urlencoded請求的數據時,會本身解碼一次,若是開發人員本身又解碼一次或屢次,就造成了雙重編碼、多重編碼。 對於multipart/form-data,非嵌入型的WAF與模塊類型的WAF,都只能本身識別並解析區分字段內容,因此在這一塊你能夠發揮本身想象,進行各類騷操做來進行繞過,可是,你應該要確認你當前所要繞過的WAF是否是真的作了這塊的內容識別。筆者的意思是說,若是它遇到這種類型Request,只是對Body內容進行所有的規則匹配,而不會解析出其中的表單內容,那你可能就不必進行那些騷操做了。實際上,有的非嵌入型WAF就是這麼「懶」。multipart/form-data的相關騷操做能夠參考Protocol-Level Evasion of Web Application Firewalls

Charset

charset是被添加在Content-Type字段後面的,用來指明消息內容所用的字符集,它也僅被後臺語言所關心。

• application/x-www-form-urlencoded;charset=ibm037
• multipart/form-data; charset=ibm037,boundary=blah
• multipart/form-data; boundary=blah ; charset=ibm037

JAVA的Servlet默認是接受大多數的charset的,不過正常點的程序員都會設置強制編碼。 有以下示例: 後臺代碼

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String userName = req.getParameter("user");
resp.getOutputStream().println("username :"+userName);
}

請求(Burpsui設置User Options-Character sets-Use a specific ..)

POST /test HTTP/1.1
Host: 127.0.0.1:8081
Content-Type: application/x-www-form-urlencoded; charset=ibm037
Content-Length: 25

%A4%A2%85%99=%99%96%96%A3

輸出

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Length: 16

username :root

至少能夠支持IBM037, IBM500, cp875, and IBM1026字符集的中間件+語言的狀況,能夠參考下面表格:

Target QueryString POST Body & and = URL-encoding
Nginx, uWSGI – Django – Python3
Nginx, uWSGI – Django – Python2 ✔ (sometimes required)
Apache Tomcat – JSP ✔ (sometimes required)
IIS – ASPX (v4.x) ✔ (optional)
IIS – ASP classic    
Apache/IIS – PHP    

 

溢量數據

筆者當初有時在瞎想,其中想到,會不會存在URI數量過多,產生繞過呢?沒想到就存在這樣的一個CVE,CVE-2018-9230-OpenResty URI參數溢出漏洞

不要緊,思想還在嘛,還存在不少的變形,如經過multipart/form-data的方式來發送數據量比較大的報文,但又屬於正常的HTTP請求,按照道理來講,對較上層的WAF(非嵌入型、模塊類型)應該會有必定殺傷力的。

傳送門——> 繞過網站WAF(圖片繞過)

HTTP協議兼容性

HTTP請求行種的空格

在RFC2616文檔中,有說到,HTTP頭部字段的構造。

SP             = <US-ASCII SP, space (32)>
HT             = <US-ASCII HT, horizontal-tab (9)>
LWS            = [CRLF] 1*( SP | HT )
message-header = field-name ":" [ field-value ]
field-name     = token
field-value    = *( field-content | LWS )
field-content  = <the OCTETs making up the field-value
and consisting of either *TEXT or combinations
of token, separators, and quoted-string>

簡單點來講就是

Test-Header: Test
等效於(空格替換成\x09)
Test-Header:  Test

但筆者發現,在請求行中,你也能夠這樣作(即使RFC2616 5.1節中指明瞭請求行中只能用空格)。因而,將一個HTTP/1.1的請求變換成以下:

OPTIONS    *   HTTP/1.1
Host:  dest.com

看着可能不明顯,但其中的SP都被筆者替換成了HT,並且,SP、HT能夠是1到多個,頭部字段中SP 、HT能夠是零個。常見的web容器都是接受這種HTTP請求的。

HTTP 0.9+Pipelining

關於這條,相關細節能夠到WAF Bypass Techniques ,筆者就不細講了。發明做者說它用這條技巧來繞過WAF(非嵌入型)對服務器上的一些目錄的訪問限制。 根據本文前面所說,能夠知道,對於嵌入型一類的WAF,是根本不可能利用pipelining來進行繞過的——嵌入型WAF得到的數據的來源是Web容器,web容器識別出這是兩個包,對於WAF也是兩個包。 不過這上面的兩點感受對WAF都沒啥用,snort都能識別,那基本上全部WAF廠商都能識別吧。不過知道多點不虧,上面第一點在筆者某次測試中仍是體現了一點價值。

Websocket、HTTP/2.0

如今愈來愈多的Web容器都開始支持比較高級的協議了,正常來講,這塊不可能不出現新的安全問題的,筆者以前簡單查看了HTTP/2.0 與Websocket的主體內容,未發現有什麼利用點,後面也未花時間去研究,寫在這裏也算給本身一個備忘錄。

 

高層數據

在一個HTTP請求中,諸如json、base64這樣的數據,是由後臺代碼調用相應的解析庫來進行解析的,即使是同結構,不一樣語言不一樣庫也可能存在一些差別。

base64

PHP解析Base64沿襲了其一向「弱」風格,即使你的字符串含有PHP非法字符串,它也能夠成功解析並處理。

測試代碼:
echo base64_decode($_POST[‘test’]);

POST提交
test=M#TIzNA==

頁面返回
1234

Unicode JSON

在HTTP請求體中傳遞JSON數據,通常狀況下若是網站用的框架,則Content-Type須要指定application/json類型;若是用了三方庫,如fastjson,content-type隨意便可。 能夠將嘗試將key或vaule替換成\uxxxx的unicode字符。

POST /json.do HTTP/1.1
Host: 127.0.0.1:8081
Content-Type: application/json
Content-Length: 68

{"\u006e\u0061\u006d\u0065":"'\u0072\u006f\u006f\u0074","age":"18"}
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/plain;charset=ISO-8859-1
Content-Length: 44

User{name=''root', age=18, contactInfo=null}

這裏的unicode關聯到JSON,只是一個實際的場景,但能夠本身發揮。

實體編碼 XML

soap之類的協議應該也屬於XML類,能夠利用這類標記語言的實體編碼特性。另外發送請求前考慮一下Content-Type類型。

POST /xml.do HTTP/1.1
Host: 127.0.0.1:8081
Content-Type: application/xml
Content-Length: 93

<?xml version="1.0" ?>
<admin>
<name>&quot;&apos;&#114;&#111;&#111;&#116;</name>
</admin>

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/plain;charset=ISO-8859-1
Content-Length: 31

Admin{name='"'root', age=null}

八進制

還有一個字符表示方式,八進制,如#十六進制的值爲23,八進制表示爲\43,也是一個可能的點,如在OGNL中就可使用。

同形字

sqlmap的tamper腳本中有個腳本,將’替換爲%ef%bc%87,聽說是UTF-8全角字符,可是這種說明沒有根本地解釋這個問題,筆者也不知道什麼環境下產生這種利用條件。直到某一天,看到一篇文章,它們之間彷佛存在某在聯繫——Unicode同形字引發的安全問題,現階段筆者也只能這樣認知這個tamper腳本。 有個趣的網站,它已經整理好了,https://www.irongeek.com/homoglyph-attack-generator.php

Char 同形
  ᅟ ᅠ ㅤ
! ! ǃ !
」 ״ ″ "
$ $ $
% % %
& & &
‘ '
( ( ﹝ (
) ) ﹞ )
* * ⁎ *
+ + +
, , ‚ ,
– ‐ -
. . ٠ ۔ ܁ ܂ ․ ‧ 。 . 。
/ / ̸ ⁄ ∕ ╱ ⫻ ⫽ / ノ
0 0 O o Ο ο О о Օ O o
1 1 I ا 1
2 2 2
3 3 3
4 4 4
5 5 5
6 6 6
7 7 7
8 8 Ց 8
9 9 9


容器語言特性

IIS %,在參數中,若是%後面不是符合URL編碼十六進制值,就會忽略該%符合,如id=%%20,等價於id=%20。 IIS asp 中的GET請求方式提交Body表單,後臺可接收。 IIS asp的參數污染中,經過,逗號鏈接污染參數。 Tomcat 路徑跳轉中容許;符號,/..;/..;/。 PHP $_REQUEST能夠接收cookie中的參數。 這塊想不到更多的了…

 

匹配緩衝區大小固定

思考一下,WAF拿到一個數據以後,在對其進行內容匹配時,是否是會將其放入一個固定大小的內存空間中,這個空間的大小是有限的。假設HTTP Request的body部分大小爲2333字節,該內存大小爲2000字節,那麼其核心引擎在作內容匹配時,是否是先處理2000字節,在處理剩下的333字節。至於如何利用,能夠發揮本身的想象。

 

白名單

一個是利用URL中的白名單,如圖片、JS等靜態資源文件。 還能夠嘗試利用下面這些頭部字段

X-Forwarded-For: 127.0.0.1
X-Client-IP: 127.0.0.1
Client-IP: 127.0.0.1

另外能夠嘗試修改Host頭部字段。

輸出角度

前面所講的都是輸入角度,這裏咱們談談輸出角度。咱們在Request中發送Pyaload,會但願從Response的回顯或基於時間這些信息通道來獲取Payload執行成功後的相關信息。若是存在某種WAF,檢測到Response中的回顯數據存在敏感信息,Resonse響應包可能就被阻斷掉了。(固然,除了基本的回顯數據通道,還有基於時間的數據通道)

OOB

遇到這種狀況,應對的方法之一就是使用OOB思想來繞過。如XXE OOB、SQL注入OOB、命令注入OOB,等等。

Range

假如頁面可能有敏感數據返回,而當前攻擊場景又利用不了OOB,你能夠嘗試使用Range方法來繞過防火牆。 普通請求與頁面結果:

POST /test/test.php HTTP/1.1
Host: 192.168.17.138
Content-Type: application/x-www-form-urlencoded
Content-Length: 9
Range: bytes=10-30

user=root
HTTP/1.1 200 OK
Server: Apache/2.4.23 (Win32) OpenSSL/1.0.2j PHP/5.2.17
Content-Length: 42
Content-Type: text/html

SELECT password from user where user = ''

添加了range,請求獲取返回頁面0到10的數據:

POST /test/test.php HTTP/1.1
Host: 192.168.17.138
Content-Type: application/x-www-form-urlencoded
Content-Length: 9
Range: bytes=0-10

user=root

HTTP/1.1 206 Partial Content
Server: Apache/2.4.23 (Win32) OpenSSL/1.0.2j PHP/5.2.17
Content-Range: bytes 0-10/394
Content-Length: 11
Content-Type: text/html

SELECT pass

添加了range,請求獲取返回頁面10到30的數據:

POST /test/test.php HTTP/1.1
Host: 192.168.17.138
Content-Type: application/x-www-form-urlencoded
Content-Length: 9
Range: bytes=10-30

user=root

HTTP/1.1 206 Partial Content
Server: Apache/2.4.23 (Win32) OpenSSL/1.0.2j PHP/5.2.17
Content-Range: bytes 10-30/394
Content-Length: 21
Content-Type: text/html

sword from user where

Range方式應該是全部Web容器默認支持的,這個東西仍是有點意思,有點做用。

 

其餘參考

傳輸層

看CVE時發現的,3whs bypass ids

Attack scenario TCP flow scheme:
Client    ->  [SYN] [Seq=0 Ack= 0]           ->  Evil Server
Client    <-  [SYN, ACK] [Seq=0 Ack= 1]      <-  Evil Server
Client    <-  [PSH, ACK] [Seq=1 Ack= 1]      <-  Evil Server  # Injection before the 3whs is completed
Client    <-  [FIN, ACK] [Seq=83 Ack= 1]     <-  Evil Server
Client    ->  [ACK] [Seq=1 Ack= 84]          ->  Evil Server
Client    ->  [PSH, ACK] [Seq=1 Ack= 84]     ->  Evil Server

在三次握手未完成以前,服務端返回了數據,能夠形成HTTP流量檢測的繞過,該種攻擊場景多是被用於掛馬、釣魚之類的。在連接中做者給出了對應的PCAP包,能夠下載來看看,算是漲見識。 在傳輸層這裏,還有一些簡單而具有實際意義的操做,好比將一個TCP報文分片成不少不少份,一份幾個字節,十幾個字節,對端服務器能正常接收,而對非嵌入型的WAF就是一個考驗;還有,咱們知道,TCP是可靠的協議,那麼咱們再將這些報文進行一個合適的亂序,那麼是否也可行。

SSL層

對於非嵌入型WAF,在解析SSL數據時,須要該SSL通訊端服務器的密鑰(非對稱)。客戶端在與Web服務器進行HTTPS通訊時,協商SSL的加密方式能夠有不少種,若是其中有一種加密方式剛好是WAF沒法識別的,那麼WAF就只能睜眼瞎了。 Bypassing Web-Application Firewalls by abusing SSL/TLS

DOS

筆者以前瞭解到,中小公司的防火牆的流量處理能力是很弱的,因此DOS確實可行,算是最後的方案。

結語

其餘說明,RFC7230對文章中所說的RFC2616的描述未發生修改。 本文參考資料彙總以下

原文連接:對過WAF的一些認知

RCF2616:https://tools.ietf.org/html/rfc2616

Bypassing Web-Application Firewalls by abusing SSL/TLS:https://0x09al.github.io/waf/bypass/ssl/2018/07/02/web-application-firewall-bypass.html

WAF Bypass Techniques  https://2018.appsec.eu/presos/HackerWAF-Bypass-TechniquesSoroush-Dalili_AppSecEU2018.pptx

Application Security Weekly: Reverse Proxies Using Weblogic, Tomcat, and Nginx:https://www.acunetix.com/blog/web-security-zone/asw-reverse-proxies-using-weblogic-tomcat-and-nginx/

Protocol-Level Evasion of Web Application Firewalls https://media.blackhat.com/bh-us-12/Briefings/Ristic/BHUS12RisticProtocolLevelSlides.pdf

Chunked HTTP transfer encoding:https://swende.se/blog/HTTPChunked.html

Impedance Mismatch and Base64:https://www.trustwave.com/en-us/resources/blogs/spiderlabs-blog/impedance-mismatch-and-base64/

HTTP 協議中的 Transfer-Encoding:https://imququ.com/post/transfer-encoding-header-in-http.html

淺談json參數解析對waf繞過的影響:https://xz.aliyun.com/t/306

3whs bypass ids:https://www.exploit-db.com/exploits/44247/

Web Application Firewall (WAF) Evasion Techniques:https://medium.com/secjuice/waf-evasion-techniques-718026d693d8

BypassWAF新思路(白名單):https://www.chainnews.com/articles/774551652625.htm

利用分塊傳輸吊打全部WAF:https://www.anquanke.com/post/id/169738

HTTP Request Smuggling:https://www.cgisecurity.com/lib/HTTP-Request-Smuggling.pdf

相關文章
相關標籤/搜索