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%。

【HTTP劫持和DNS劫持】实际JS对抗的更多相关文章

  1. 【HTTP劫持和DNS劫持】腾讯的实际业务分析

        简单介绍一下HTTP劫持和DNS劫持的概念,也就是运营商通过某些方式篡改了用户正常访问的网页,插入广告或者其他一些杂七杂八的东西.       首先对运营商的劫持行为做一些分析,他们的目的无非 ...

  2. HTTP劫持和DNS劫持

    HTTP劫持和DNS劫持 首先对运营商的劫持行为做一些分析,他们的目的无非就是赚钱,而赚钱的方式有两种: 1.对正常网站加入额外的广告,这包括网页内浮层或弹出广告窗口: 2.针对一些广告联盟或带推广链 ...

  3. 关于全站https必要性http流量劫持、dns劫持等相关技术

    关于全站https必要性http流量劫持.dns劫持等相关技术 微信已经要求微信支付,申请退款功能必须12月7号之前必须使用https证书了(其他目前为建议使用https),IOS也是2017年1月1 ...

  4. 一文搞懂│XSS攻击、SQL注入、CSRF攻击、DDOS攻击、DNS劫持

    目录 XSS 攻击 SQL 注入 CSRF 攻击 DDOS 攻击 DNS 劫持 XSS 攻击 全称跨站脚本攻击 Cross Site Scripting 为了与重叠样式表 CSS 进行区分,所以换了另 ...

  5. DNS 劫持、HTTP 劫持与 DNS 污染

    本文为本人的学习笔记,不保证正确. DNS 劫持 指DNS服务器被控制,查询DNS时,服务器直接返回给你它想让你看的信息.这种问题常为 ISP 所为. 由于一般的的电脑的 DNS 服务器 的配置都为自 ...

  6. 手把手教你DNS劫持挂马

    出品|MS08067实验室(www.ms08067.com) 本文作者:BlackCat(Ms08067内网安全小组成员) 首先学习DNS劫持之前,务必要了解下DNS是个什么玩意. DNS(域名系统) ...

  7. 无线安全: 通过伪AP进行DHCP+DNS劫持的钓鱼攻击

    有了之前学习802.11的数据帧格式.芯片硬件参数学习的基础后,我们接下来继续学习无线安全中黑客是怎样进行流量劫持攻击的 相关学习资料 http://www.freebuf.com/articles/ ...

  8. Kali 局域网 DNS 劫持

    <一> 所需工具  1: Kali-linux-2017  2: ettercap 0.8.2 3: web 服务器, 这里以 node 为例 <二> 原理  1: DNS劫持 ...

  9. openwrt-智能路由器hack技术(1)---"DNS劫持"

    openwrt-智能路由器hack技术(1)---"DNS劫持" 1   导读 PS:之前写的一个文章,现在发现结构内容排版不是太好,导致阅读体验太差,影响传播和SEO,所以现在整 ...

随机推荐

  1. 我听说 C...

    我听说在 c 语言的世界里,goto 和异常处理都是声名狼藉的东西,而我认为它们在一起就能化解各自的问题.

  2. Django 中related_name,"%(app_label)s_%(class)s_related"

    先看个model from django.db import models # Create your models here. class Parent(models.Model): name = ...

  3. json相关的一些用法

    一. json可以表示3种类型的值:   简单值 . 对象. 数组    表示对象时:>1. 没有变量的概念 ,所以不用申明变量                    >2. 没有末尾结束 ...

  4. js判断undefined类型

    js判断undefined类型 if (reValue== undefined){    alert("undefined");    }  发现判断不出来,最后查了下资料要用ty ...

  5. Excel Sheet Column Title

    Given a positive integer, return its corresponding column title as appear in an Excel sheet. For exa ...

  6. 使用nodeJs安装Vue-cli

    TIP:win10下安装,使用管理员身份进行,否则会有权限限制. 1,安装完成node,node有自带的npm,可以直接在cmd中,找到nodeJs安装的路径下,进行命令行全局安装vue-cli.(n ...

  7. Java学习【1】

    一.Java 简介 Java是由Sun Microsystems公司于1995年5月推出的Java面向对象程序设计语言和Java平台的总称. 2005年6月,SUN公司公开Java SE 6.Java ...

  8. java执行linux命令

    package com.gtstar.collector; import java.io.BufferedReader;import java.io.IOException;import java.i ...

  9. Centos 编写 service 启动

    Centos 系统服务脚本目录: [html] view plaincopyprint?   /usr/lib/systemd/ 有系统(system)和用户(user)之分, 如需要开机没有登陆情况 ...

  10. AndroidStudio错误总结及解决(待续)

    AndroidStudio错误总结及解决 一. 当安装好AndroidStudio开启的时候出现如下错误: 百度的解决方法: 1)进入刚安装的Android Studio目录下的bin目录.找到ide ...