HTTP request smuggling

Iam_Wander
7 min readApr 21, 2024

--

Hello Everyone, this is yet another continuation to the HTTP request smuggling smuggling. This writeup is meant to cover the advanced topics and showcase on the various ways we can

  1. Bypass access controls via HTTP/2 request tunnelling.
  2. Perform Web cache poisoning via HTTP/2 request tunnelling.
  3. Perform a Client-side de sync to induce the victims browser to reveal cookies
  4. We can perform a Server-side pause-based request smuggling

Lab: Bypassing access controls via HTTP/2 request Tunnelling.

In this Lab, the Front-End downgrades HTTP/2 requests and fails to properly sanitize incoming headers. To solve the lab, we are required to compromise the admin and delete the user Carlos.

Admittedly, i found this type of vulnerability a bit difficult to detect and defend. More so, this kind of vulnerability can be highly impactful if you come across it in a real pentest/bug-bounty.

The Approach

First we begin with recon. Observe that the application has a search feature that is reflected client side and a comment section.

Proxy all the request to burp.

Take note of the content-length as this will come in handy during the last bits of the lab.

To prove that this vulnerability exists, we will try to inject headers with CRLF on the root of the application while keeping the request to HTTP /2 and point it to a host header that does not exist (say test.com).

We get a timeout connecting to test.com.

With that in mind, we need to find an endpoint that might leak internal headers. In this case, i found the search engine functionality to be the best bet.

Change the request method to post.

Remove the Content-Length and the search=hacker as the front-end will ignore the cl and as for the search parameter we will introduce it in the inspector tab.

We get the cookie value revealed in the response, this means that we can reveal more headers if we increase the value of the content-length.

Setting the Content-Length to 140, we get more internal headers revealed.

We can use these internal headers to login as admin.

The Exploit

We try accessing the admin panel using the internal headers we retrieved as shown above. Notice some alterations i made.

X-SSL-VERIFIED: 1
X-SSL-CLIENT-CN: administrator
X-FRONTEND-KEY: 1645084333875830
  1. X-SSL-VERIFIED: means that we are verified,unlike the 0 which was previously used.
  2. X-SSL-CLIENT-CN: stands for Common Name. in this instance the name should be administrator.

We get a response for the front page and not that of the admin page.

What happens if we change the request method from GET to POST,PUT,HEAD.

Using a HEAD request to the home page of the application we receive a very juicy error message.

“Server Error: Received only 3608 of expected 8760 bytes of data”

This means, the path / renders 8760 but the server only received 3608 bytes of data.

We can work around this by identifying a path with 3608 bytes or less.

We try path /admin

We still do not get enough response for the admin. This is because the content-length for the admin path is still too small.

We need to identify a path with more bytes than 2790 yet less than 3608.

If you recall from the first recon, the /?search=hacker had 3406 bytes, that may work fine.

We get the admin panel.

With little efforts,we can now delete the user carlos.

Web cache poisoning via HTTP/2 request tunnelling

Here,we will work around on how we can poison the cache in such a way that when the victim visits the home page, their browser executes alert(1).

A victim user will visit the home page every 15 seconds.

In this scenario, the front end does not reuse the connection to the back-end server so it isn’t vulnerable to a classic request smuggling attack, so the only way around it is through a request tunneling attack.

This vulnerability is rampant in with many web applications i have come across.

The Approach

We will start by confirming that the request smuggling attack works by smuggling a request to an end-point that does not exist.

We can this as follows:

We get a 404 not found, and this is POC that vulnerability exists.

Exploitation

To exploit this, we can add a cache buster parameter that we can use only us to confirm that the smuggled request is working. if it works we can remove the cache parameter to smuggle the request to the actual front page.

I will demonstrate all these with screenshots.

As you can see, we introduced an arbitrary path /?cachebuster=1 HTTP/1.1 and smuggled a GET request to /post?postId=9. We expected to view the content of the post but instead we receive the contents of the home page.

This is because the web app has a blind request-smuggling vulnerability since the front end is reading the back-end result following what the content-length telling it, and that’s the home page.

However we can turn this attack to a non-blind attack by changing the request method from GET to Head. This works because a HEAD request makes the front-end to read from the headers and not the content-length.

Notice that we now get the request headers for our smuggled request.

However, there is a catch to this that you should understand. If you send a request with a lesser content length than that of the home page, you get a timeout.

The web server expected 8350 bytes of character but instead got 11 bytes only.

Now we need to identify a sink that reflects user input in the response and and inject our JavaScript.

To achieve this, find a path to a resource and delete a couple of directories until you find a 302 redirect to the specified resource path which we can inject our JavaScript payload.

And it works!!!

We encounter the same problem as before. The bytes expected from the smuggled request were lesser than that of the home page. So we need to add more bytes to it. We need to print at least 8800 A characters.

We do so as follows.

We get the response as expected.

To poison the home page, we need to get rid of the ?cachebuster=2. simply leave the path blank.

Works !! We have poisoned the cache successfully.

--

--

No responses yet