4.1.ChunkedTransferCodingThe 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-partCRLF 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 octetsThe 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
<?phpini_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加载的规则拦截了请求包中的关键字“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
(
)
请求:
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>