This is a write-up of a security bug I found a few months ago - HTTP Request Smuggling (Type: CL.TE).
This vulnerability occurs due to a disagreement between the front-end and back-end server on how to parse incoming HTTP request streams.
CL.TE arises when the front-end server uses the Content-Length header and the back-end server uses the Transfer-Encoding header to parse the incoming HTTP request, which causes a desynchronization.
To get more in-depth understanding of the underlying concepts of this vulnerability, I suggest reading this for additional reference.
Example:
POST / HTTP/1.1 Host: test.com Content-Length: 12 Transfer-Encoding: chunked 0\r\n \r\n TESTING
In the above example, the front-end server parses the Content-Length header (till the end of TESTING [12 bytes]. I have used \r\n for demonstrating why 12 bytes is the content length in this example. These bytes are not visible in the original request.
Now, once this request is received by back-end server, it parses Transfer-Encoding header (which is of length zero in this case). So, it ends up not processing the remaining body (marked in red). This unprocessed data will be now treated as the start of the next request in the sequence.
I hope now you have some clarity on the vulnerability I'll exploit in this write-up. Here are the steps that I followed:
1. I used the tool Smuggler to identify target websites in my scope that may be vulnerable to HTTP Request Smuggling.
2. The tool generated the below payload:
3. The above payload only detects the vulnerability using time-based techniques, hence some alteration is needed to verify whether the endpoint is actually vulnerable. So, I crafted a payload that will poison the backend with the request to a non-existent page. I used Burp Repeater to send the following HTTP Request (Note the space before Transfer-Encoding header):
4. Send the request to Turbo Intruder. Wordlist can be any list containing any characters.
Poisoned Response (Unexpected 404 error returned due to the malicious “GET /404 HTTP/1.1” request):
6. On sending a normal GET request to /404 the target endpoint, the below response is received, whose content length matches the above poisoned response, thus proving a successful attack:
7. On further testing, I found an endpoint, which includes image as logo from any arbitrary domain. Generally, this bug requires user to click on a specially crafted URL. But, by chaining it with the above CLTE attack, this dependency was bypassed. As a result, when the user visits the poisoned web server’s page, it automatically gets the defaced page as a response.
Thanks for reading!