Cenzic 232 Patent
Paid Advertising
sla.ckers.org is
ha.ckers sla.cking
Sla.ckers.org
This group should mostly be dealing with how web applications enable networking security issues that are otherwise not there. Everything is being tunneled over port 80 now so what does that enable and how do we fix it? 
Go to Topic: PreviousNext
Go to: Forum ListMessage ListNew TopicSearchLog In
Tampering with websockets
Posted by: holiman
Date: January 11, 2011 08:21AM

I have been experimenting a bit with websockets, mostly to intercept and tamper with websocket traffic. In order to do so, I am using Jetty and the default chat-application which is bundled in the release ( > 7.0). I use google chrome as a browser.

Anyway, I am testing approaches to, on the client side, tamper with data
a) before it is sent to the server and
b) when it is received, before it is handled by the application javascript.

The case a) can be fixed in a pretty general manner by overriding the send-method in WebSocket prototype, by executing the following in the browser:
window.WebSocket.prototype.oldSend = window.WebSocket.prototype.send;
window.WebSocket.prototype.send=function(data){
var toSend = prompt("Sending data",data);
this.oldSend(toSend);
}

However, I have not found any generic approach to intercept messages as they are received, since onmessage is not defined in the prototype but (in the case of jetty) is monkey-patched to the actual websocket-object post creation.
So, I have only made a jetty-chat-specific interception which looks like this:

room._ws.old_onmessage=room._ws.onmessage;
room._ws.onmessage=function(message){
var data = prompt("Receiving data",message.data);
room._ws.old_onmessage({data:data});
}

I have also tried using eventhandling to capture the message event, but had the same problem there : I haven't been able to add eventhandlers to the WebSocket prototype object, only to the actual instance (and my events are handled *after* onmessage is called) :
function handler(message)
{
var data = prompt("Receiving data",message.data);
}

window.room._ws.addEventListener('message',handler,true);

Interception of websocket traffic seems to be a bit of a black hole, or maybe I am just a very unskilled googler. Any ideas on this subject?

Options: ReplyQuote
Re: Tampering with websockets
Posted by: Gareth Heyes
Date: January 11, 2011 04:45PM

Not tested this but how about:-

window.WebSocket.prototype.__defineSetter__('onmessage', function() {
});

or

Object.defineProperty(window.WebSocket.prototype, 'onmessage', {set:function(){}});

------------------------------------------------------------------------------------------------------------
"People who say it cannot be done should not interrupt those who are doing it.";
labs : [www.businessinfo.co.uk]
blog : [www.thespanner.co.uk]
Hackvertor : [hackvertor.co.uk]

Options: ReplyQuote
Re: Tampering with websockets
Posted by: holiman
Date: January 12, 2011 09:35AM

Nope, these do not seem to work.

window.WebSocket.prototype.__defineSetter__('onmessage', function(val) { alert(val); });
room._ws.onmessage=function(data){alert(data)}; ==> Nothing shows

room._ws.__defineSetter__('onmessage', function(val) { alert(val); });
room._ws.onmessage=function(data){alert(data)}; ==> Alerts the new function

The prototype does not seem to be called when onmessage is set explicitly on the object (?).

Object.defineProperty(window.WebSocket.prototype, 'onmessage', {set:function(){alert(1)}});
room._ws.onmessage=function(data){alert(data)}; ) ==> Nothing happens

Options: ReplyQuote
Re: Tampering with websockets
Posted by: holiman
Date: January 12, 2011 09:44AM

This piece of code is not dependant on jetty, can be tested in the chrome console. I don't know why it does not work, but I am no guru either... :

window.WebSocket.prototype.__defineSetter__('onmessage', function(val) { alert(val); });
x=new WebSocket("ws://localhost:8080/ws/");
x.onmessage=function(){alert(2);}

Options: ReplyQuote
Re: Tampering with websockets
Posted by: holiman
Date: January 12, 2011 10:02AM

I got it!


// Performed only once
var oldWebSocket=window.WebSocket;
function WrappedWebSocket(loc)
{
this.ws=new oldWebSocket(loc);
this.__defineSetter__('onmessage', function(val) { alert(val); });
}
window.WebSocket=WrappedWebSocket

//Example of application trying to use websocket
x=new WebSocket("ws://localhost:8080/ws/");
x.onmessage=function(){alert(2);}

Options: ReplyQuote
Re: Tampering with websockets
Posted by: Gareth Heyes
Date: January 12, 2011 10:10AM

Nice! Good thinking

I'd wrap it in a closure though because it's tidier:-
window.WebSocket = function(oldWebSocket) {
     return function WrappedWebSocket(loc) {
         this.ws=new oldWebSocket(loc);
         this.__defineSetter__('onmessage', function(val) { alert(val); });
     }
}(window.WebSocket)

------------------------------------------------------------------------------------------------------------
"People who say it cannot be done should not interrupt those who are doing it.";
labs : [www.businessinfo.co.uk]
blog : [www.thespanner.co.uk]
Hackvertor : [hackvertor.co.uk]



Edited 1 time(s). Last edit at 01/12/2011 10:19AM by Gareth Heyes.

Options: ReplyQuote
Re: Tampering with websockets
Posted by: holiman
Date: January 12, 2011 10:39AM

I just made this more complete wrap:
var oldWebSocket=window.WebSocket;
function WrappedWebSocket(loc)
{
	this.prototype=new oldWebSocket(loc);
	this.__proto__=this.prototype;
	var wrapper=this;
	this.onmessage=function(message)
	{
		var data = prompt("Receiving data",message.data);
		wrapper.trueonmessage({data:data});
	}
	this.__defineSetter__('onmessage', function(val){
					wrapper.trueonmessage=val;
				});
}
window.WebSocket=WrappedWebSocket
Going to take a look at your example and tidy up mine a bit more



Edited 1 time(s). Last edit at 01/12/2011 10:49AM by holiman.

Options: ReplyQuote
Re: Tampering with websockets
Posted by: holiman
Date: January 12, 2011 10:41AM

ps. How do I add code formatting to my posts?

Options: ReplyQuote
Re: Tampering with websockets
Posted by: Gareth Heyes
Date: January 12, 2011 10:44AM

[ code ]

[ / code ]

------------------------------------------------------------------------------------------------------------
"People who say it cannot be done should not interrupt those who are doing it.";
labs : [www.businessinfo.co.uk]
blog : [www.thespanner.co.uk]
Hackvertor : [hackvertor.co.uk]

Options: ReplyQuote
Re: Tampering with websockets
Posted by: holiman
Date: January 12, 2011 10:48AM

Thanks a bunch!

Here is the websocket-tampering super-mega-framework in all its entirety and glory:

window.WebSocket = function(oldWebSocket) {
	return function WrappedWebSocket(loc)
	{
		this.prototype=new oldWebSocket(loc);
		this.__proto__=this.prototype;
		var wrapper=this;
		this.onmessage=function(message)
		{
			var data = prompt("Receiving data",message.data);
			wrapper.trueonmessage({data: data});
		};
		this.__defineSetter__('onmessage', function(val){wrapper.trueonmessage=val;});
		this.send=function(data){this.prototype.send(prompt("Sending data",data));};
	};
}(window.WebSocket);



Edited 1 time(s). Last edit at 01/12/2011 11:18AM by holiman.

Options: ReplyQuote
Re: Tampering with websockets
Posted by: holiman
Date: January 12, 2011 10:56AM

One annoying thing is that if I seem to be unable to set the message.data directly, which is why I am sending a {data:data}-object into the "trueonmessage"-function. Not happy about that..

Options: ReplyQuote
Re: Tampering with websockets
Posted by: Gareth Heyes
Date: January 12, 2011 10:56AM

oooo sweet much more sexier now :D

btw backtracking a bit did you try the technique mentioned earlier with the Object.prototype instead of the WebSocket prototype that could work for getting message

------------------------------------------------------------------------------------------------------------
"People who say it cannot be done should not interrupt those who are doing it.";
labs : [www.businessinfo.co.uk]
blog : [www.thespanner.co.uk]
Hackvertor : [hackvertor.co.uk]



Edited 1 time(s). Last edit at 01/12/2011 10:59AM by Gareth Heyes.

Options: ReplyQuote
Re: Tampering with websockets
Posted by: holiman
Date: January 12, 2011 11:07AM

Gareth Heyes Wrote:
-------------------------------------------------------
> oooo sweet much more sexier now :D
>
> btw backtracking a bit did you try the technique
> mentioned earlier with the Object.prototype
> instead of the WebSocket prototype that could work
> for getting message

Yes, I mentioned it above:
Object.defineProperty(window.WebSocket.prototype, 'onmessage', {set:function(){alert(1)}}); 
room._ws.onmessage=function(data){alert(data)}; ) ==> Nothing happens
I had no luck with that, and it was a bit too esoteric for me to dive into why

Also, I would like to make it into a bookmarklet, but chrome tells me that I have an "Uncaught SyntaxError: Unexpected token this".



Edited 2 time(s). Last edit at 01/12/2011 11:09AM by holiman.

Options: ReplyQuote
Re: Tampering with websockets
Posted by: holiman
Date: January 12, 2011 11:15AM

A few semi-colons were missing.

Bookmarklet:

javascript:window.WebSocket = function(oldWebSocket) {return function WrappedWebSocket(loc){this.prototype=new oldWebSocket(loc);this.__proto__=this.prototype;var wrapper=this;this.onmessage=function(message){var data = prompt("Receiving data",message.data);wrapper.trueonmessage({data: data});};this.__defineSetter__('onmessage', function(val){wrapper.trueonmessage=val;});this.send=function(data){this.prototype.send(prompt("Sending data",data));};};}(window.WebSocket);

Options: ReplyQuote


Sorry, only registered users may post in this forum.