Inspecting WebSocket frames in an undetectable way

后端 未结 2 651
忘了有多久
忘了有多久 2020-11-29 05:47

How I can read WebSocket frames of a web page in a Chrome extension or Firefox add-on, in a way that cannot be detected by the page?

Inspect WebSockets frames from a

2条回答
  •  误落风尘
    2020-11-29 06:16

    There is an alternative to Rob W's method that completely masks any interaction with the page (for Chrome)

    Namely, you can take out some heavy artillery and use chrome.debugger.

    Note that using it will stop you from opening Dev Tools for the page in question (or, more precisely, opening the Dev Tools will make it stop working, since only one debugger client can connect). This has been improved since: multiple debuggers can be attached.

    This is a pretty low-level API; you'll need to construct your queries using the debugger protocol yourself. Also, the corresponding events are not in the 1.1 documentation, you'll need to look at the development version.

    You should be able to receive WebSocket events like those and examine their payloadData:

    {"method":"Network.webSocketFrameSent","params":{"requestId":"3080.31","timestamp":18090.353684,"response":{"opcode":1,"mask":true,"payloadData":"Rock it with HTML5 WebSocket"}}}
    {"method":"Network.webSocketFrameReceived","params":{"requestId":"3080.31","timestamp":18090.454617,"response":{"opcode":1,"mask":false,"payloadData":"Rock it with HTML5 WebSocket"}}}
    

    This extension sample should provide a starting point.

    In fact, here's a starting point, assuming tabId is the tab you're interested in:

    chrome.debugger.attach({tabId:tab.id}, "1.1", function() {
      chrome.debugger.sendCommand({tabId:tabId}, "Network.enable");
      chrome.debugger.onEvent.addListener(onEvent);
    });
    
    function onEvent(debuggeeId, message, params) {
      if (tabId != debuggeeId.tabId)
        return;
    
      if (message == "Network.webSocketFrameSent") {
        // do something with params.response.payloadData,
        //   it contains the data SENT
      } else if (message == "Network.webSocketFrameReceived") {
        // do something with params.response.payloadData,
        //   it contains the data RECEIVED
      }
    }
    

    I have tested this approach (with the linked sample modified as above) and it works.

提交回复
热议问题