【纯干货】"X度文库"恶意脚本分析与反制(续集)

"死灰复燃"的恶意脚本行为分析

本文承接上文,没看过的同学可以先大致了解一下背景。现在X度文库已经注意到了自家文档被恶意脚本复制传播的问题,设计了一些反制策略,比如将文档渲染为 canvas。但是,恶意脚本的迭代速度也没落下,且其实现成本十分低廉。下面我截取了一段恶意脚本的关键实现代码,借此分析恶意脚本是如何对抗x度文库的防复制策略的。

document.createElement = new Proxy(document.createElement, {
    apply: function (target, thisArg, argumentsList) {
        var element = Reflect.apply(target, thisArg, argumentsList);
        if (argumentsList[0] === "canvas") {
            var tmpData_1 = {
                canvas: element,
                data: [],
            };
            element.getContext("2d").fillText = function () {
                var args = [];
                for (var _i = 0; _i < arguments.length; _i++) {
                    args[_i] = arguments[_i];
                }
                tmpData_1.data.push(args);
                originObject.context2DPrototype.fillText.apply(this, args);
            };
            canvasDataGroup.push(tmpData_1);
        }
        return element;
    },
});
复制代码

这段代码有几个关键点,一是利用Proxy劫持document.createElement,二是 Hook 每个canvas实例的关键绘制函数,即fillText,从而拿到格式化后的明文信息。恶意脚本的具体行为可以参照下面这个图。

恶意脚本路径.drawio.png

基于 WASM 的反制

上篇文章中已经说明了为什么要选择 WASM 来提高前端的安全性,这里不再赘述。在 WASM 中只要操作 dom 或 bom 就一定会被恶意脚本以同样的方式劫持并 Hook,因此解密后的明文信息不能通过浏览器提供的任何渲染接口来绘制。基于此,我想到了直接把文字当成一个个像素点绘制到一张图片中,这需要在 WASM 中提供处理图片信息的能力。所幸,已经有开源库完成了这部分工作,如 imageimageproc。由于这些开源库与底层文件系统与图形系统不进行耦合(这点很重要,因为 WASM 提供的是一个沙箱环境),所以它们都可以很好在 WASM 环境上运行。

具体流程图变化不大,只是修改了绘制明文的方式。

image.png 下面我们具体看看引入 WASM 后如何反制恶意脚本。

反制.drawio.png

恶意脚本最关键的第五步已经失效了,因为在 WASM 层与 dom 的交互,仅仅是将处理后的图片通过 putImageData 来绘制到 canvas 上,即使对 putImageData 进行 Hook 也仅仅只能拿到图片数据,而图片数据要倒推回明文信息,那只能够通过 OCR 来进行解析。具体实现代码已贴到附录。

实现效果

具体实现效果可以看下图:

image-20220329211921692.png

总结

通过分析恶意脚本的行为,我们发现恶意脚本想要劫持和 Hook 那些 dom 和 bom 的方法和对象是十分简单的,不管x度文库做了多大努力,恶意脚本都可以轻松的以同样的思路来破解。我认为,问题的本质就在于 js 代码的可读性较强(即使经过了打包和混淆),而且 js 很容易被注入和动态调试,而 wasm 经过编译后其可读性已经很差了而且也没法注入和动态调试(仅为个人认知,欢迎讨论)。所以通过把关键函数乃至渲染放到 WASM 中能大大提高破解成本。当然如果最后祭出了 OCR 大法,在浏览器层面是没法解决的(有本事来客户端碰一碰)。

附录

  1. 具体实现源码 - github.com/ascodelife/…

参考文章

  1. canvas fillText 接口 - developer.mozilla.org/zh-CN/docs/…
  2. Proxy - developer.mozilla.org/zh-CN/docs/…
  3. WebAssembly 介绍 - developer.mozilla.org/zh-CN/docs/…
  4. wasm-bindgen 文档 - rustwasm.github.io/wasm-bindge…
  5. canvas putImageData 接口 - developer.mozilla.org/zh-CN/docs/…
  6. rust image 开源库 - github.com/image-rs/im…
  7. rust imageproc 开源库 - github.com/image-rs/im…

猜你喜欢

转载自juejin.im/post/7080528388984668197