javascript - 以不可检测的方式检查 WebSocket 帧

标签 javascript google-chrome google-chrome-extension websocket firefox-addon

如何在 Chrome 扩展程序或 Firefox 附加组件中读取网页的 WebSocket 帧,而页面无法检测到该帧?

Inspect WebSockets frames from a Chrome Dev Tools extension制定了一个类似的问题,但开发 NPAPI 插件不再有意义,因为它很快就会被删除。

最佳答案

拦截 WebSocket 数据很容易。只需在页面构造 WebSocket 之前执行以下脚本即可。此代码段对 WebSocket 构造函数进行猴子修补:创建新的 WebSocket 构造函数时,该代码段会订阅 message 事件,您可以从中对数据执行任何操作.

此代码段旨在与 native 代码无法区分,因此页面无法轻易检测到修改(但是,请参阅本文末尾的备注)。

(function() {
    var OrigWebSocket = window.WebSocket;
    var callWebSocket = OrigWebSocket.apply.bind(OrigWebSocket);
    var wsAddListener = OrigWebSocket.prototype.addEventListener;
    wsAddListener = wsAddListener.call.bind(wsAddListener);
    window.WebSocket = function WebSocket(url, protocols) {
        var ws;
        if (!(this instanceof WebSocket)) {
            // Called without 'new' (browsers will throw an error).
            ws = callWebSocket(this, arguments);
        } else if (arguments.length === 1) {
            ws = new OrigWebSocket(url);
        } else if (arguments.length >= 2) {
            ws = new OrigWebSocket(url, protocols);
        } else { // No arguments (browsers will throw an error)
            ws = new OrigWebSocket();
        }

        wsAddListener(ws, 'message', function(event) {
            // TODO: Do something with event.data (received data) if you wish.
        });
        return ws;
    }.bind();
    window.WebSocket.prototype = OrigWebSocket.prototype;
    window.WebSocket.prototype.constructor = window.WebSocket;

    var wsSend = OrigWebSocket.prototype.send;
    wsSend = wsSend.apply.bind(wsSend);
    OrigWebSocket.prototype.send = function(data) {
        // TODO: Do something with the sent data if you wish.
        return wsSend(this, arguments);
    };
})();

在 Chrome 扩展程序中,该代码段可以通过 content script 运行使用 run_at:'document_start',请参阅 Insert code into the page context using a content script .

Firefox 还支持 content scripts ,同样的逻辑适用(使用 contentScriptWhen:'start')。

注意:前面的代码片段被设计为在页面其余部分之前执行时与 native 代码没有区别。检测这些修改的唯一(不寻常且脆弱的)方法是:

  • 将无效参数传递给 WebSocket 构造函数,捕获错误并检查依赖于实现(特定于浏览器)的堆栈跟踪。如果堆栈帧比平时多一个,则构造函数可能被篡改(从页面的 Angular 来看)。

  • 序列化构造函数。未修改的构造函数变为 function WebSocket() { [native code] },而修补后的构造函数看起来像 function () { [native code] } (此问题仅存在于Chrome;在 Firefox 中,序列化是相同的)。

  • 序列化 WebSocket.prototype.send 方法。由于该函数未绑定(bind),对其进行序列化 (WebSocket.prototype.send.toString()) 会揭示非 native 实现。这可以通过重写 .send.toString 方法来缓解,页面又可以通过与 Function.prototype.toString 的严格比较检测到该方法。如果您不需要发送的数据,请不要覆盖 OrigWebSocket.prototype.send

关于javascript - 以不可检测的方式检查 WebSocket 帧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31181651/

相关文章:

javascript - isPresent 和 isElementPresent 之间的区别

javascript - https 页面上的 Chrome 扩展内容脚本?

javascript - 在 chrome 扩展中调用通知函数时打开不同的页面定义?

JavaScript 图像 slider 在图像之间不褪色

javascript - 压缩脚本和样式并将所有 js 和样式引用组合成单个引用以优化站点性能

javascript - 在 jquery/javascript 中设置关注构造框的问题?

javascript - 如何禁用 smartWizard 插件上的可点击 anchor ?

javascript - 谷歌浏览器扩展程序: Alert when Modal/popup closed

html - Chrome 中 CSS 3D 元素的悬停状态检测

javascript - 将选项卡重定向到我的页面的 Chrome 扩展