【HTTP劫持和DNS劫持】实际JS对抗

1、对于DIV注入的,可以初始化时检查全部html代码。

检测是否被劫持比较简单,但对抗就略麻烦,这个在说完第2点之后再解释。

2、对于js注入,可以在window监听DOMNodeInserted事件。

事件有srcElement,可以获取到刚插入的dom节点。 这里开始简单粗暴的做正则匹配,匹配所有url。 再逐个比较是否白名单域名,如果不是,则判定为劫持。可以上报,同时可以移除dom.parentNode.removeChild(dom); 但这样容易造成误伤,因为正常页面中可能有外部链接,或者一些纯文本url。

    function checkDivHijack(e) {
        var html = e ? (e.srcElement.outerHTML || e.srcElement.wholeText) : $('html').html();
        var reg = /http:\/\/([\w.:]+\/)[^'"\s]+/g;
        var urlList = html.match(reg);
        if (!urlList || urlList.length == 0) {
            return;
        }
        reg = /^http:\/\/(.*\.qq\.com|.*\.gtimg\.cn|.*\.qlogo\.cn|.*\.qpic\.cn|.*\.wanggou\.com|.*\.jd\.com)\/$/;
        var hijack = false;
        for (var i = 0; i < urlList.length; i++) {
            if (!reg.test(urlList[i])) {
                hijack = true;
                break;
            }
        }
     }

后来改为

    function checkDivHijack(e) {
        var dom = e ? e.srcElement : document.documentElement;
        if (!dom.outerHTML) {
            return;     //e不是一个dom,只是插入一段文本
        }

        var imgList = (dom.nodeName.toUpperCase() == 'IMG') ? [dom] : dom.getElementsByTagName('img');
        if (!imgList || imgList.length == 0) {
            return;
        }

        var httpReg = /^http:\/\/(.*\.qq\.com|.*\.gtimg\.cn|.*\.qlogo\.cn|.*\.qpic\.cn)\//;
        var base64Reg = /^data:image/;
        var src;
        var hijack = false;
        for (var i = 0; i < imgList.length; i++) {
            src = imgList[i].src;
            if (!httpReg.test(src) && !base64Reg.test(src)) {
                hijack = true;
                break;
            }
        }
     }

但这样也有漏洞,如果运营商通过div+style设置背景的方式显示广告图,上述代码就无法检查出来。

那么,就还需要检查style的情况,但style情况就更复杂了。可能是<style>,也可能是inline样式,最终还是要回到url识别上。 那么做个折衷,我们继续用最初的纯文本正则匹配url的方式,但跳过纯文本的情况(例如修改div的内容,替换为一段文本),只检查插入dom的情况。 具体方法是

        if (!dom.outerHTML) {
            return;     //e不是一个dom,只是插入一段文本
        }

回到刚才第一点的问题,监测第一点的情况,可以用一样的做法。但是,对抗就麻烦很多,因为广告dom节点可以插在body第一层,也可以插在某个内容div中。如果简单粗暴的把广告dom节点到body的全部div都移除,可能会造成大面积的误伤。 所以,针对这个情况,我们还在做进一步的监测统计。

3、对于iframe的情况,要检测非常简单,只需要比较self和top是否相同。

不过,要完整解决这个嵌套劫持,就要知道运营商的小把戏。 试想一下,iframe前,请求http://www.host.com/xxx.html ,就被劫持,302重定向到一个iframe的页面,这个页面使用iframe重新加载我们原来要请求的html。 那么,此时在iframe中的html为什么能够顺利加载回来呢?而不是又被劫持? 我们猜想,运营商应该在url中加了一个参数,标记是否已经劫持过。 而实际监测发现,我们的猜想也是正确的。

呃,我们仔细看,还可以发现运营商做这个劫持也非常粗暴,如果页面依赖hash,就会引起错误了。

见招拆招,这个比较好办,我们只需要把top的地址修改为self地址即可。一来冲掉iframe,二来绕过劫持。

    function checkIframeHijack() {
        var flag = 'iframe_hijack_redirected';
        if (getURLParam(flag)) {
            sendHijackReport('jiankang.hijack.iframe_ad', 'iframe hijack: ' + location.href);
        } else {
            if (self != top) {
                var url = location.href;
                var parts = url.split('#');
                if (location.search) {
                    parts[0] += '&' + flag + '=1';
                } else {
                    parts[0] += '?' + flag + '=1';
                }
                try {
                    top.location = parts.join('#');
                } catch (e) {
                }
            }
        }
    }

为了安全起见,防止运营商有新招数,所以这里只尝试一次,用iframe_hijack_redirected参数标记,已经尝试过。

按照统计情况来看,运营商还是挺猖狂的,平均大约有6~10个劫持上报,大概占整个QQ健康用户的3%到5%。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏FreeBuf

无线网络嗅探中的Radiotap

引言 在WLAN无线网络抓包的时候不管是用wireshark、tcpdump还是scapy都会出现Radiotap、LLC、SNAP协议层。 如图所示: ? L...

3868
来自专栏Flutter入门

偶遇FFMpeg(四)-FFmpeg PC端推流

之前在Android集成FFmpeg。主要还是基于命令行的方式进行操作。刚刚好最近又在研究推流相关的东西。看了一些博文。和做了一些实践。 就希望通过本文记录袭...

2883
来自专栏CDA数据分析师

SAS | 如何网络爬虫抓取网页数据

本人刚刚完成SAS正则表达式的学习,初学SAS网络爬虫,看到过一些前辈大牛们爬虫程序,感觉很有趣。现在结合实际例子,浅谈一下怎么做一些最基本的网页数据抓取。第一...

3108
来自专栏涂小刚的专栏

从 PageRank Example 谈 Spark 应用程序调优

在做PageRank测试时,发现有很多有趣的调优点,想到这些调优点可能对用户来说是普遍有效的,现把它整理出来一一分析,以供大家参考。

1K3
来自专栏IT派

美剧迷是如何使用Python的

一直有爱看美剧的习惯,一方面锻炼一下英语听力,一方面打发一下时间。之前是能在视频网站上面在线看的,可是自从广电总局的限制令之后,进口的美剧英剧等貌似就不在像以前...

1122
来自专栏Albert陈凯

理解zookeeper选举机制

zookeeper集群 配置多个实例共同构成一个集群对外提供服务以达到水平扩展的目的,每个服务器上的数据是相同的,每一个服务器均可以对外提供读和写的服务,这点...

5315
来自专栏Android相关

处理器结构--MicroOp &&MacroOp Fusion

也成为微指令操作融合,将多个相同的汇编指令编译的uops融合到一个微指令中,使得ALU在执行指令时可以在一个Cycle中执行完毕,提高指令执行的吞吐量

1183
来自专栏我就是马云飞

RxJava2 实战知识梳理(2) - 计算一段时间内数据的平均值

前言 今天,我们继续跟着 RxJava-Android-Samples 的脚步,一起看一下RxJava2在实战当中的应用,在这个项目中,第二个的例子的描述如下:...

2356
来自专栏Crossin的编程教室

Python 爬虫爬取美剧网站

一直有爱看美剧的习惯,一方面锻炼一下英语听力,一方面打发一下时间。之前是能在视频网站上面在线看的,可是自从广电总局的限制令之后,进口的美剧英剧等貌似就不在像以前...

3827
来自专栏Java技术

你应该知道的缓存进化史!

本文是上周去技术沙龙听了一下爱奇艺的Java缓存之路有感写出来的。先简单介绍一下爱奇艺的java缓存道路的发展吧。

1151

扫码关注云+社区