HTTP Request Smuggling CL.TE
Persistence is key, do it for the learning, not for the bounty ;)
Not all bounties are a success, this is a story about how I tried harder when failing. (As full time Security Consultant I spent my own time on this which was about 1 week and I don’t regret the learning experience)
To make this process easier I’d recommend using the Burp plugin “HTTP Request Smuggler”. I used that plugin and tried manually too but I just didn’t take any screenshots of the plugin. It would be a pain if you didn’t use this Burp plugin for TE.CL.
I ran out of time as the target was taken off from Synack but I spent most of the time on bypassing the backend, however I tried/attempted all of the following: (some worked, some didn’t plus I ran out of time)
- Using HTTP request smuggling to bypass front-end security controls
- Revealing front-end request rewriting
- Capturing other users’ requests
- Using HTTP request smuggling to exploit reflected XSS
- Using HTTP request smuggling to turn an on-site redirect into an open redirect
- Using HTTP request smuggling to perform web cache poisoning
- Using HTTP request smuggling to perform web cache deception
(For more information please refer to Portswigger’s blog)
I highly recommend finishing all the labs so you don’t have to go back and forth like me :p
HTTP request smuggling CL.TE is a web application vulnerability which allows an attacker to smuggle multiple HTTP request by tricking the front-end (load balancer or reverse proxy) to forward multiple HTTP requests to a back-end server over the same network connection and the protocol used for the back-end connections carries the risk that the two servers disagree about the boundaries between requests.
In CL.TE the front-end server uses the Content-Length header and the back-end server uses the Transfer-Encoding header.
I found my first HTTP request smuggling CL.TE attack on Synack Red Team which was confirmed from the request shown in
Figure 1 .
The first thing that came to mind is to make a successful request to see the response to give me another confirmation shown in
The next thing I added was
localhost to the Host header, however there seemed to be a problem as shown in
Figure 3 .
(I tried many other things too, not just robots.txt)
In the Synack description and based on the IP address the target was using AWS EC2 instance. I then happily to tried to access the
/latest/meta-data/and changed the Host header to
169.254.169.254, which is an AWS IP address for accessing internal resources.
I soon realised that I hadn’t finished the entire Web Security Academy exercises so I decided to go back and do some more research.
After a bit of research I soon realised that Portswigger blog mentioned that the request can be blocked due to the second request’s Host header conflicting with the smuggled Host header in the first request.
I then issued the request shown in
Figure 5so the second request’s headers are appended to the smuggled request body instead and don’t conflict with each other.
I also tried the request to
/latest/meta-data/ as shown in
Figure 6 which failed.
By now I had tried a lot of requests which failed. Normally this would work depending on the web application. I decided to do more labs and more research.
Revealing front-end request rewriting
I then came across revealing front-end request rewriting.
In many of the web application the front-end (load balancer or reverse proxy) might rewrite requests prior to being sent to the backend server, usually by adding extra headers to HTTP requests.
These headers could be:
- terminate the TLS connection and add some headers describing the protocol and ciphers that were used;
- add an X-Forwarded-For header containing the user’s IP address;
- determine the user’s ID based on their session token and add a header identifying the user; or
- add some sensitive information that is of interest for other attacks.
In some cases HTTP request smuggling will fail if some of these headers are missing as the back-end server might not process these requests in a way it normally does.
You can leak these headers using the following steps:
- Find a POST request that reflects the value of a request parameter into the application’s response.
- Shuffle the parameters so that the reflected parameter appears last in the message body.
- Smuggle this request to the back-end server, followed directly by a normal request whose rewritten form you want to reveal.
So I performed the steps above and leaked the headers, at this point I was pretty happy as this was a step forward after some research,
Figure 7 .
This is what the headers looked like when they were decoded.
GET / HTTP/1.1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36
Accept: text/html,application/xhtml xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding: gzip, deflate
Transfer-Encoding : chunked0
So I attempted all possible combinations with the headers, even the ones that did not make sense. I had spent almost one week on this vulnerability, researching it, doing the labs, attempting to do it on the target etc…..
As you can see whenever I add the Host header without the name of the target, it gives me 403. Otherwise resources such as meta-data give me 404 and resources such as robots.txt give me 200 (with targets name in Host header).
As soon as I changed the header to something other than the targets name, once again 403 even for something like robots.txt
AT LAST! I did something different here, I changed the protocol from HTTP/1.1 to HTTP/1.0 on both requests and I got a 302 Found.
I was redirected to SSO and it took me to a login portal, the server was publicly accessible too however it requires SAML to take you to the login portal I believe.
Here is the login portal
It seems that the backend requires some sort of authentication (maybe?) in order to access internal resources which sounds like a rare case but could be possible. What are your thoughts?…….Hope this helps.
I have submitted the bug (lower impact than usual) and received a bounty, thank you Synack :)
Recommendations (From PortSwigger)
- Disable reuse of back-end connections, so that each back-end request is sent over a separate network connection.
- Use HTTP/2 for back-end connections, as this protocol prevents ambiguity about the boundaries between requests.
- Use exactly the same web server software for the front-end and back-end servers, so that they agree about the boundaries between requests.
What is HTTP request smuggling? Tutorial & Examples
In this section, we'll explain HTTP request smuggling attacks and describe how common request smuggling vulnerabilities…
Finding HTTP request smuggling vulnerabilities
In this section, we'll explain different techniques for finding HTTP request smuggling vulnerabilities. The most…
Exploiting HTTP request smuggling vulnerabilities
In this section, we'll describe various ways in which HTTP request smuggling vulnerabilities can be exploited…
HTTP Desync Attacks: Request Smuggling Reborn
HTTP requests are traditionally viewed as isolated, standalone entities. In this paper, I'll explore forgotten…
Instance Metadata and User Data
The AWS Documentation website is getting a new look!Try it now and let us know what you think. Switch to the new look…
- James Kettle (@albinowax)
- Web Security Academy
- Dr. Frans Lategan (@fransla)