PS: This article is for technical analysis only and is prohibited for other illegal uses.
First, let me introduce myself. I’m a novice who started learning Web penetration testing in 2017. The reason? Of course, my own website was hacked…
Getting to the point, as security awareness increases, enterprises are paying more attention to the security of their websites. However, many web applications are outdated or seek convenience by wanting to secure their applications at minimal cost, so they only install WAF on their servers. Therefore, during penetration testing, we often encounter annoying web application firewalls, and only by breaking through this first line of defense can subsequent penetration proceed smoothly. This article demonstrates bypassing WAF at the protocol level using SQL injection, but is not limited to testing SQL injection in actual applications (command execution, code execution, file upload, etc. are all applicable).
Disclaimer: The methods and ideas presented in this experiment are not original; they are summarized from a public lecture by a certain expert.
Principle
Send payload packets to the server so that the WAF cannot recognize the payload while the web containers like Apache and Tomcat can parse its content normally. As shown in Figure 1.

Figure 1
Experimental Environment
Local machine: Windows 10 + XAMPP + the latest version of a certain dog WAF. For demonstration purposes, the script with SQL injection uses $_REQUEST[“id”] to receive data submitted via GET or POST. The WAF is configured to intercept URL and POST requests containing ‘and’ or ‘or’ injections, as shown in Figure 2.

Figure 2
GET requests or POST requests sent using the Hackbar plugin are intercepted, as shown in Figure 3.
Figure 3
1. Bypassing Using Pipeline [This method may be intercepted by a certain dog]
Principle:
The HTTP protocol is encapsulated by the TCP protocol. When a browser initiates an HTTP request, it first establishes a TCP connection with the server and then sends the HTTP data packet (i.e., the data intercepted by Burp Suite), which contains a Connection field, usually set to ‘close’. Web containers like Apache decide whether to keep the TCP connection open or close it based on this field. When the content sent is too large and exceeds the capacity of one HTTP packet, it needs to be sent in multiple parts, and the value will change to ‘keep-alive’, meaning the TCP connection established for this HTTP request will not close until the content being sent ends with ‘Connection: close’.
1. Disable Burp’s Repeater automatic Content-Length update, as shown in Figure 4. Click on the red circle of Repeater and uncheck ‘update Content-Length’ in the dropdown options. This step is crucial!!!

Figure 4
2. Intercept the POST submission in Burp
id=1 and 1=1
, which shows it was intercepted by the WAF, as shown in Figure 5.
Figure 5
3. Copy the data packet from Figure 5 and paste it
id=1 and 1=1
after it, as shown in Figure 6.
Figure 6
4. Next, modify the data part of the first data packet, changing
id=1+and+1%3D1
to the normal content id=1, then set the Content-Length value of the data packet to the character length of the modified [id=1], which is 4, and finally set the Connection field value to ‘keep-alive’. After submission, as shown in Figure 7, two response packets will be returned, corresponding to the two requests.

Figure 7
Note: From the results, the first normal data packet returned the correct content, while the second packet containing the payload was intercepted by a certain dog WAF, indicating that both packets reached the server. In the face of other WAFs, it may be possible to bypass them. Regardless, this is still a method worth learning and understanding, and it can be combined with the following methods for bypassing.
2. Bypassing Using Chunked Transfer Encoding [This method can bypass a certain dog]
Principle:
By adding Transfer-Encoding: chunked to the header, it indicates that this message uses chunked encoding. At this point, the data part of the POST request message needs to be transmitted using a series of chunks. Each chunk contains a hexadecimal length value and data, with the length value occupying its own line, excluding the ending of the chunk data, and finally ending with a 0 on its own line.
1. Enable the previously disabled content-length automatic update from the last experiment. Add Transfer-Encoding: chunked to the POST request packet, then chunk the data part id=1 and 1=1 (note that the length value must be in hexadecimal), with each chunk having its length value on one line and data on the next line, as shown in Figure 8.
Figure 8
2. Change the data in the packet from Figure 8
id=1 and 1=1
to
id=1 and 1=2
by changing the 1 in the 4th chunk of Figure 8 to 2. As shown in Figure 9, no data is returned, indicating the payload is effective.
Figure 9
Note: Chunked transfer encoding requires splitting keywords like and, or, select, union, etc., otherwise it will still be intercepted by the WAF. During encoding, the length must include the length of spaces. Finally, end with 0 and leave two empty lines after 0 to indicate the end of the data packet, otherwise, clicking the submit button will result in a waiting state.
3. Bypassing Using Uncovered Protocol [This will also be intercepted by a certain dog]
Principle:
The Content-Type in the HTTP header generally includes application/x-www-form-urlencoded, multipart/form-data, and text/plain. Among them, multipart/form-data indicates that the data is encoded as a message, with each control on the page corresponding to a part of the message. Therefore, when the WAF has no rules matching the data transmitted by this protocol, it can be bypassed.
1. Change the Content-Type header to multipart/form-data; boundary=69 and then set the Content-Disposition name in the separator to the name of the parameter to be passed. The data part is placed on the line above the end separator.
Figure 10
Since it is a normal data submission, as shown in Figure 10, the data can be correctly parsed by the Apache container. Attempting 1 and 1=1 will also be intercepted by a certain dog WAF, but if other WAFs have no rules to intercept data packets submitted in this way, they can also be bypassed.
2. Generally, bypassing WAFs often requires a combination of multiple methods. For example, in the example in Figure 10, simply changing the data part 1 and 1=1 to use a dot ‘.’ as a connector, i.e., 1.and 1=1, can achieve a bypass effect. Of course, this is just the effect of using a dot as a connector. As shown in Figure 11.
Figure 11
4. Combining Chunked Encoding + Uncovered Protocol Bypass
1. In the data packet of the uncovered protocol, add Transfer-Encoding: chunked, then chunk the entire data part, as shown in Figure 12 (the data part is 1 and 1=1).
Figure 12
Note: The 2nd, 3rd, 7th, and 8th chunks.
In the 2nd chunk, it needs to satisfy
length value<br />empty line<br />Content-Disposition: name="id"<br />empty line
in this format, and the length value must include the length of the two empty lines (the length of an empty line is 2).
The 3rd chunk, which is the beginning of the data, must satisfy
length value<br />empty line<br />data
in this format, and the empty line must be included in the length calculation.
The 7th chunk, which is the end of the boundary, must satisfy
length value<br />empty line<br />end separator<br />empty line
in this format, and the empty line length must be included in the calculation.
The 8th chunk must satisfy
0<br />empty line<br />empty line
in this format. If these four format requirements are not met, the payload will not be effective.
Conclusion:
The above discusses bypassing WAF at the HTTP protocol level. Since it is relatively universal, it can theoretically be used in various aspects of penetration testing, such as command execution, code injection, SQL injection, etc. Although only chunked encoding truly bypassed a certain dog in this article, the other two methods may still be applicable in bypassing other WAFs and can be combined with other bypass methods, even used in combination as shown in section four.
*Author: bypassword. This article belongs to the FreeBuf original reward program and is prohibited from being reproduced without permission.
