Windows – Inspecting websocket traffic with proxy

androidman-in-the-middlePROXYtlswindows

I'm using Charles Proxy to inspect traffic from my Android apps. I have the phone configured to proxy all traffic through Charles, which is installed on my PC.

Everything has worked thus far (HTTP/HTTPS traffic) except for websocket traffic. I have been unable to inspect it in Charles and Fiddler. First, the CONNECT request fails as follows:

URL https://184.73.XX.XX/
Status  Failed
Failure Invalid first line in request
Response Code   -
Protocol    HTTP/1.0
Method  CONNECT
Content-Type    -
Client Address  /192.168.0.10
Remote Address  184.73.XX.XX/184.73.XX.XX

And right after this request, there is an additional request sent to upgrade the connection, which appears to be successful as seen in the response:

HTTP/1.1 101 Switching Protocols
Server: nginx
Date: Sun, 16 Feb 2014 02:04:33 GMT
Connection: upgrade
Upgrade: websocket
Sec-WebSocket-Accept: CKm+rgmiltNrbQvwU2HzKHzr2eM=

After that, traffic from the app stops appearing even though activity continues. So, what is it about websocket traffic that it isn't captured by the proxy? Also, how can I capture it to see what is being sent back and forth?

I have tried Wireshark and I see TLS traffic continuing after the CONNECT/upgrade request, but I don't know how to reconstruct the packets into something I can understand, and to decrypt the TLS encrypted traffic.

Best Answer

Found the answer myself in case anyone is interested (source is blogs.telerik.com)

WebSockets

Fiddler’s HTML5 WebSockets support continues to grow; Fiddler extensions can now capture and manipulate WebSocket messages by handling the FiddlerApplication.OnWebSocketMessage event.

In preparation for a full-featured WebSockets UI, Fiddler no longer spews WebSocket messages to the Log tab. If you’d like to re-enable that behavior until the full UI is available, you can do so using FiddlerScript. Simply click Rules > Customize Rules and add the following function inside your Handlers class.

static function OnWebSocketMessage(oMsg: WebSocketMessage) {

// Log Message to the LOG tab
FiddlerApplication.Log.LogString(oMsg.ToString());

/*
// Modify a message's content
var sPayload = oMsg.PayloadAsString();
if (sPayload.Contains("time")) {
    oMsg.SetPayload(sPayload + "... bazinga!");
}                            
*/
}
Related Question