
Intercepting WebSocket traffic in a Chrome extension is a powerful tool for debugging and testing web applications. This guide will walk you through the process of intercepting WebSocket traffic.
To start, you'll need to create a new Chrome extension and add the necessary permissions to access WebSocket traffic. This can be done by adding the "activeTab" and "webSockets" permissions to your extension's manifest file.
You'll also need to use the chrome.webSocket.onMessage event to listen for WebSocket messages. This event is fired whenever a WebSocket message is received, allowing you to intercept and inspect the message data.
By following these steps, you can gain a deeper understanding of WebSocket traffic and improve your debugging and testing workflow.
Blocking WebSocket
Blocking WebSocket is a powerful tool in Chrome extension development. It allows event handlers to modify network requests.
The BlockingResponse returns a value for event handlers that have the 'blocking' extraInfoSpec applied, which gives the event handler the ability to modify network requests. This is a key feature for developers who want to intercept and manipulate WebSocket traffic.
By using the BlockingResponse, developers can create event handlers that can block or modify WebSocket requests, giving them more control over the network traffic in their extension. This can be useful for debugging or for implementing custom logic in the extension.
The BlockingResponse is a flexible tool that can be used in a variety of ways, from blocking malicious WebSocket requests to modifying the content of WebSocket messages.
Debugging WebSocket
Debugging WebSocket connections can be a bit tricky, but with the right tools and approach, it's definitely doable.
To start debugging, you'll need to master Chrome tools, specifically the debugger, which can only be accessed within a sandboxed background "service worker." This means you'll need to communicate any data collected to the foreground content windows.
The debugger is limited to being accessed within a service worker, which lacks DOM access, so all data for rendering must be communicated to the foreground via messaging.
Expand your knowledge: Websocket Service
To examine data from a specific tab or window, the debugger must first be attached to that tab or window. You can do this by monitoring changes to tabs using `chrome.tabs.onUpdated.addListener`.
Once you've attached the debugger to any tab, a warning banner will appear on all tabs to ensure the user is aware of the extension's actions.
The warning banner cannot be closed without interrupting the debugger connection, so it's essential to attach and detach listeners carefully to avoid this issue.
Here are some key events to listen for when debugging WebSocket connections:
- `Network.webSocketCreated`
- `Network.webSocketClosed`
- `Network.webSocketFrameSent`
- `Network.webSocketFrameReceived`
These events will give you valuable information about the WebSocket connection, including the `tabId`, `requestId`, and `params` object, which contains relevant information about the send/receive.
By listening for these events, you can track the data coming from any particular WebSocket in any desired tab, facilitating precise monitoring and analysis.
Once you've set up your listeners, you can explore a list of messages to find the ones relevant to your needs. The `debuggeeId` object will include the `tabId` of the tab from which the WebSocket data originated.
Here's a summary of the key information you can expect to receive:
- `tabId`
- `requestId`
- `params` object (containing relevant information about the send/receive)
With this information, you can output the desired content into the console logs for analysis or debugging purposes.
By following these steps and listening for the right events, you can effectively debug WebSocket connections using Chrome tools and gain valuable insights into your extension's behavior.
WebSocket Tools
To effectively use the WebSocket tools, you can monitor when the debugger is detached, either due to user cancellation or the tab being closed, and use this event for cleanup.
You can attach a listener to the `chrome.debugger.onDetach` event to track when the debugger is detached from a tab. This can be done by adding a listener that checks if the debugger is still attached to a tab, and if not, it removes the listener.
The `chrome.debugger.onEvent.removeListener(handleDebuggerEvent)` line is used to remove the listener when all attached debuggers have been removed. This is important to avoid duplicate messages being received.
Here are the relevant WebSocket events:
- Network.webSocketCreated: triggered when a WebSocket is created
- Network.webSocketClosed: triggered when a WebSocket is closed
- Network.webSocketFrameSent: triggered when a WebSocket frame is sent
- Network.webSocketFrameReceived: triggered when a WebSocket frame is received
These events provide valuable information about the WebSocket data, including the `tabId`, `requestId`, `response`, and `url` parameters.
WebSocket Tool Access
To access the WebSocket debugger, you'll need to attach it to a tab or window within your service worker. This can be done using the `chrome.tabs.onUpdated.addListener` event, which allows you to monitor changes to tabs and attach the debugger accordingly.
The debugger can only be accessed within a sandboxed background "service worker", and any data collected must be transferred to the foreground content windows. Since service workers lack document object model (DOM) access, all data for rendering must be communicated to the foreground via messaging.
To avoid the constant appearance of the warning banner, it's essential to detach listeners when they're no longer needed. This can be done by monitoring the `chrome.debugger.onDetach` event, which is triggered when the debugger is detached from a tab due to user cancellation or the tab being closed.
The warning banner cannot be closed without interrupting the debugger connection. To avoid this, you can attach and detach listeners as needed, and remove them when they're no longer necessary.
Here are the four message types that are of interest when using the WebSocket debugger:
- Network.webSocketCreated
- Network.webSocketClosed
- Network.webSocketFrameSent
- Network.webSocketFrameReceived
These events provide valuable information about WebSocket connections, including the tabId, requestId, and payload of the send/receive. By tracking these events, you can gain a deeper understanding of WebSocket behavior and identify potential issues.
Example: Keepalive
To keep a service worker active, you can send a keepalive message every 20 seconds. This is started once the service worker connects to the WebSocket.
You'll need to set the minimum Chrome version to 116 in the manifest to support WebSockets in service workers. This ensures your extension only runs in compatible browsers.
The keepalive is implemented using the setInterval function in the service worker, which regularly sends a ping to the server while there is an active WebSocket connection.
Intercepting WebSocket
You can access the WebSocket debug tool in Chrome to monitor WebSocket connections and intercept messages. This is useful for debugging and analyzing WebSocket traffic.
To intercept WebSocket messages, you can attach a debugger and set up a listener to receive events. The `chrome.debugger.onDetach` event can be used to monitor when the debugger is detached, either due to user cancellation or the tab being closed.
The `chrome.debugger.onEvent` event can be used to receive WebSocket events, such as `Network.webSocketCreated`, `Network.webSocketClosed`, `Network.webSocketFrameSent`, and `Network.webSocketFrameReceived`. You can use these events to intercept WebSocket messages and analyze the data.
Here are the WebSocket events that can be intercepted:
- Network.webSocketCreated
- Network.webSocketClosed
- Network.webSocketFrameSent
- Network.webSocketFrameReceived
Each event contains relevant information, such as the `tabId` of the tab from which the WebSocket data originated, and the `params` object, which contains the message data. You can use this information to analyze the WebSocket traffic and intercept messages as needed.
By using the WebSocket debug tool and setting up a listener to receive events, you can intercept WebSocket messages and gain a deeper understanding of the WebSocket traffic in your application.
Lab Scenario
In our lab scenario, we have a Kali machine (192.63.134.2) and a Web server (192.63.134.3 or target-1). The user or practitioner will get a graphical user interface (GUI) access to the Kali machine, through the web browser.
The lab is designed to practice intercepting WebSocket messages, a crucial skill for any cybersecurity professional. This lab is a great way to get hands-on experience with WebSocket messages and learn how to intercept them.
Suggestion: Responsive Web Design Chrome Extension
The Kali machine is the attacking machine, and the Web server is the target machine. The practitioner will need to use various tools and techniques to intercept the WebSocket messages and retrieve the flag.
Here are the key details about the lab setup:
- Kali machine IP: 192.63.134.2
- Web server IP: 192.63.134.3 or target-1
- GUI access to Kali machine through web browser
This lab scenario is an excellent way to learn about WebSocket messages and how to intercept them. By practicing in a controlled environment, you'll be better prepared to tackle real-world challenges.
On Before Request
The onBeforeRequest event is fired when a request is about to occur. This event allows us to intercept WebSocket messages.
The callback function for onBeforeRequest looks like (details: object) => BlockingResponse | undefined. This means we can modify the request or block it altogether.
We can use the filterRequestFilter parameter to filter out specific requests. This can be useful if we only want to intercept certain types of WebSocket messages.
The extraInfoSpecOnBeforeRequestOptions parameter is optional and provides additional information about the request. We can use this to make informed decisions about whether to block or modify the request.
Here's a breakdown of the onBeforeRequest callback function parameters:
On Response Started
The onResponseStarted event is fired when the first byte of the response body is received, which means the status line and response headers are available.
This event is particularly useful for HTTP requests, where you can access the response headers and status line.
The callback function looks like this: (details:object) =>void, where details is an object containing information about the event.
The onResponseStarted event also accepts a filterRequestFilter parameter, which allows you to filter the request.
The extraInfoSpecOnResponseStartedOptions array is optional and can be used to specify additional information about the event.
You might like: Websocket Headers
Example and Tools
The WebSocket debugger is a powerful tool for monitoring and analyzing WebSocket connections in Chrome extensions. You can access and utilize it by attaching a listener to the `chrome.debugger.onDetach` event.
This listener will be notified when the debugger is detached, either due to user cancellation or the tab being closed. You can use this event for cleanup, such as removing unnecessary listeners.
To avoid chaos, only attach one listener to the debugger, unless you intend to use multiple listener callbacks. This will prevent duplicate messages from being received.
Once you have a debugger attached and a listener set up, you can explore a list of messages to find the ones relevant to your needs. There are four types of messages that are of interest: 'Network.webSocketCreated', 'Network.webSocketClosed', 'Network.webSocketFrameSent', and 'Network.webSocketFrameReceived'.
Here's an example of how to handle these events:
```javascript
function handleDebuggerEvent(debuggeeId, message, params) {
switch (message) {
case 'Network.webSocketCreated':
traceSocketCreate(debuggeeId, params);
break;
case 'Network.webSocketClosed':
traceSocketClose(debuggeeId, params);
break;
case 'Network.webSocketFrameSent':
traceSocketSend(debuggeeId, params);
break;
case 'Network.webSocketFrameReceived':
traceSocketReceive(debuggeeId, params);
break;
default:
}
}
```
The `params` object within the `debuggeeId` will contain relevant information, particularly of interest to your specific needs. Here's a breakdown of the information you can expect to find:
- requestId — The unique identifier for the WebSocket connection
- response — The payload of the send/receive
- requestId — The unique identifier for the WebSocket connection
- url — The destination endpoint for the WebSocket
- requestId — The unique identifier for the WebSocket connection
The combination of `tabId` + `requestId` enables unique tracking of data coming from any particular WebSocket in any desired tab, facilitating precise monitoring and analysis.
Featured Images: pexels.com


