WebSocket Man In The Middle

go back / p4p1


Created on Tue. 13 Oct 2021


ad logo

Let's have a laugh! I often sit around at home thinking on what to hack next. I've been looking at websocket for a few weeks wanting to up my bug bounty game. So I figured wouldn't it be cool to do a Man In The Middle but with websockets!

Before I start quick disclaimer, there will be no wireshark and networking man in the middle. I went with a different approach this time. I figured if I could just plug myself to the WebSocket API it would be a lot cooler. And I could learn more :) so here we go!

The beginning

So I was hanging out on the web and was messing around on a website that had websocket implemented to handle sessions during voice calls. So if you look at Burp Suite it has a tab for websockets but you cant really edit them on the fly (What I wanted to do btw).

So I started researching a bit on how I could plug into websockets and I fell on this website

Reading this I was like Jesus yes! This is exactly what my brain was craving reimplementing WebSockets. This was what I needed in my life :) So I figured if I wanted to do that I should sit down and learn WebSockets a bit more. Yes I've never used them before Lol.

Testing

So I then pivoted to writing a websocket echo client with websocat as the server. This would help me learn the basics and then maybe reimplement the different components! So I ran on my machine the following command to spin up a websocket server:

          
            $ websocat -l 1234
          
        

After that I built a basic page to mess around with:

Basically this page connects to ws://localhost:1234/ and sends basic text. I wanted to create a simple chat client from server -> client and vis versa.

In purple I create the websocket instance used to handle the connections. In green I define the code that will be run when the connection opens. In red is the code for when the websocket clients receives a message. In white is the code for when I want to send a message to the server. Like said this client is a basic as I can get it from there I started looking at some code I found online of people reimplementing the websocket interface to see their approach.

After seeing this line I had a kind of Vietnam flash back of doom from when I started learning Javascript. I get it it does look cool when people code like this. But its useless and cumbersome to read. So I figured I could figure out a solution on my own. So I opened the JS console and starting looking at the types returned by the websocket function.

Seeing this did confuse me a lot I was dumb founded that WebSocket was just a function when you would use the dot operator to call send() and such. Which was very confusing to me. I looked more online and then...

The Breakthrough

          
          class WebSocket {
            constructor(url, protocols) {
              this.ws = new window.WebSocket(url, protocols);
            }
            set onopen(eventfunc) {
              this.ws.onopen = function(event) {
                eventfunc(event);
              };
            }
          }
          
        

After going back through the torture that was the reimplementation of the other guy I saw something interesting:

Why was those get's and set's there I googled it for a bit and quickly understood that those where like operator overloading in C++. I never thought that would be useful one day. So I smashed together the above code and it then for some reason worked! Amazing!

Grunt Work

From there I now had to implement the rest of the WebSocket API not knowing how big it was I looked up online how to do that and scoped out the task. Thankfully mozilla did most of the work for me and mapped out the API on this cool website.

From there seeing there was not that much to do I sat down and sprinted through all of them reimplementing the ones I needed first and gave a test spin. I decided to simply print the text inside of the console to see if I could extract the data:

From there I decided to code some more and make the class from a small script to a proper reimplementation.

Before

After

Now that that was done I was stuck on a problem when using this script I needed it to be called before any websocket implementation. And the objective was to be able to use this on any website without really editing the source code of the website. Now if you find an XSS you could use this script to ex filtrate data from the websocket connections and I will be adding this script to XSS bomb in the patch where I add websockets.

Going Further

So to get around the issue I was having I decided to implement the JS file inside of a chrome extension to make the impact of this bigger. Maybe a threat actor would infect the web browser with that extension to steal conversations over websockets on tech support platform. Kind of like chat with our tech support team through you web browser.

For avid readers of my blog you guys know that I have a bit of experience with chrome extensions so I decided at 1AM to write one LOL. So I started by writing the manifest.json file which is mandatory inside of extensions.

So after some research I discovered that when you load a js file inside of a chrome extension it will most of the time load last which is the opposite from what I want. So I found this work around I first have to edit the manifest file with the run_at section and add 3 lines of code to my script and voila!

Now I do have to take the class minify it and then put it inside of the innerHTML section to be able to load it inside of a script tag which is added at the top of the body! Now that was better.


Thank you for reading this different post. I hope it was pretty cool. I will be back for more soon as usual. To the right is the resulting script for everyone to try out :) I also uploaded the websocket testing page that I used so that if you want to give a shot at setting up the extension and running the backend with websocat on port 1234. You can do a live demo!