HTTP Response Smuggling / Desync
- Do you work in a cybersecurity company? Do you want to see your company advertised in HackTricks? or do you want to have access to the latest version of the PEASS or download HackTricks in PDF? Check the SUBSCRIPTION PLANS!
First of all, this technique abuses a HTTP Request Smuggling vulnerability, so you need to know what that is:
The main difference between this technique and a common HTTP Request smuggling is that instead of attacking the request of the victim by adding a prefix to it, we are going to leak or modify the response the victim receives. This is done by, instead of sending 1 request and a half to abuse the HTTP Request smuggling, send 2 complete requests to desynchronise the proxies responses queue.
This is because we are going to be able to desynchronise the response queue so the response from the legit request of the victim is sent to the attacker, or by injecting attackers controlled content in the response to the victim.
HTTP/1.1 allows to ask for different resources without needing to wait for previous ones. Therefore, if there is a proxy in the middle, it's the proxies task to maintain a synchronised match of requests sent to the backend and responses coming from it.
However, there is a problem desynchronising the responses queue. If an attacker send a HTTP Response smuggling attack and the responses to the initial request and the smuggled one are responded immediately, the smuggled response won't be inserted inside the queue of the victim response but will just be discarded as an error.
Therefore, it's needed that the smuggled request takes more time to be processed inside the back-end server. Therefore, by the time the smuggled request is processed, the communication with the attacker will be over.
If in this specific situation a victim has sent a request and the smuggled request is responded before the legitimate request, the smuggled response will be sent to the victim. Therefore, the attacker will be controlling the request "performed" by the victim.
Moreover, is the attacker then perform a request and the legitimate response to the victim request is answered before the attackers request. The response to the victim is going to be sent to the attacker, stealing the response to the victim (which can contains for example the header Set-Cookie).
Another interesting difference with common HTTP Request Smuggling is that, in a common smuggling attack, the goal is to modify the beginning of the victims request so it perform an unexpected action. In a HTTP Response smuggling attack, as you are sending full requests, you can inject in one payload tens of responses that will be desynchronising tens of users that will be receiving the injected responses.
Apart from being able to distribute more easily tens of exploits across legitimate users, this could also be used to cause a DoS in the server.
As explained previously, in order to abuse this technique, it's needed that the first smuggled message into the server requires a lot of time to be processed.
This time consuming request is enough if we just want to try to steal the victims response. But if you want to perform a more complex exploit this will be a common structure for the exploit.
First of all the initial request abusing HTTP Request smuggling, then the time consuming request and then 1 or more payload requests that whose responses will be sent to the victims.
As with HTTP Request Smuggling known payloads, you can steal the victims request with one important difference: In this case you just need the send content to be reflected in the response, no persistent storage is needed.
First, the attacker send a payload containing a final POST request with the reflected parameter at the end and a large Content-Length
Then, once the initial request (blue) was processed and while the sleepy one is being processed (yellow) the next request that arrives from a victim is going to be appended in the queue just after the reflected parameter:
Then, the victim will receive the response to the sleepy request and if in the meantime the attacker sent another request, the response from the reflected content request will be sent to him.
Up to this point, we have learned how to abuse HTTP Request Smuggling attacks to control the request whose response a client is going to receive and how you can then steal the response that was meant for the victim.
But it's still possible to desynchronise even more the responses.
There are interesting requests like HEAD request that are specified to not have any content inside the responses body and that should (must) contain the Content-Length of the request like if it was a GET request.
Therefore, if an attacker injects a HEAD request, like in this images:
Then, once the blue one is responded to the attacker, the next victims request is going to be introduced in the queue:
Then, the victim will receive the response from the HEAD request, which is going to contain a Content-Length but no content at all. Therefore, the proxy won't send this response to the victim, but will wait for some content, which actually is going to be response to the yellow request (also injected by the attacker):
Following the previous example, knowing that you can control the body of the request whose response is going to receive the victim and that a HEAD response usually contains in its headers the Content-Type and the Content-Length, you can send a request like the following one to cause XSS in the victim without the page being vulnerable to XSS:
Abusing the previously commented response desynchronisation Content Confusion attack, if the cache stores the response to the request performed by the victim and this response is an injected one causing a XSS, then the cache is poisoned.
Malicious request containing the XSS payload:
Malicious response to the victim that contains the header that indicates to the cache to store the response:
This attack is similar to the previous one, but instead of injecting a payload inside the cache, the attacker will be caching victim information inside of the cache:
The goal of this attack is to abuse again the response desynchronisation in order to make the proxy send a 100% attacker generated response.
In order to achieve this, the attacker needs to find an endpoint of the web application that is reflecting some values inside the response and know the content length of the HEAD response.
He will send a exploit like:
After the first request is resolved and sent back to the attacker, the victims request is added into the queue:
The victim will receive as response the HEAD response + the content of the second request response (containing part of the reflected data):
However, note how the reflected data had a size according to the Content-Length of the HEAD response that generated a valid HTTP response in the response queue.
Therefore, the next request of the second victim will be receiving as response something completely crafted by the attacker. As the response is completely crafted by the attacker he can also make the proxy cache the response.