浅谈运营商劫持那些事

当我们打开一个网页,经常会弹出一堆格格不入的小广告,像牛皮鲜一样,不堪入目;打开的是A网站,莫名其妙却被跳转至B网站;明明想下的是A软件,下载安装后却是B软件…

—— 我的电脑中毒了?
—— 错!你的互联网流量被劫持,被蹂躏了!
—— ???
——请看下面分解!

运营商劫持的目的就是为了带来源源不断的收入。

劫持的技术

  • DNS劫持:DNS劫持又称域名劫持,是指在劫持的网络范围内拦截域名解析的请求,分析请求的域名,把审查范围以外的请求放行,否则返回假的IP地址或者什么都不做使请求失去响应,其效果就是对特定的网络不能反应或访问的是假网址。——百度百科《DNS劫持》
  • HTTP劫持:在用户的浏览器连上被访问的网站服务器,发送了HTTP请求后,运营商的路由器会首先收到此次HTTP请求,之后运营商路由器的旁路设备标记此TCP连接为HTTP协议,之后可以抢在网站服务器返回数据之前发送HTTP协议的302代码进行下载软件的劫持,浏览器收到302代码后就会跳转到错误的软件下载地址下载软件了,随后网站服务器的真正数据到达后反而会被丢弃。或者,旁路设备在标记此TCP连接为HTTP协议后,直接返回修改后的HTML代码,导致浏览器中被插入了运营商的广告,随后网站服务器的真正数据到达后最终也是被丢弃。——月光博客

劫持的效果分为两种

  • 跳转劫持(访问A网站却跳到B网站)
  • 内容劫持(加入广告,替换链接)

劫持原因

根本原因在于HTTP协议本身的一些安全缺陷

HTTP缺陷

  • 明文传输
  • 不验证身份
  • 没有数据完整性校验

有效的解决劫持的HTTPS

  • 内容加密 让监听者拿到消息也看不懂
  • 证书 用一个权威的机构(CA)和证书来证明通信双方的身份
  • 完整性校验

前端劫持的对策

——投诉增值业务部门进而投诉工信部?
——NO!费时费力,只是杯水车薪之位,大多不能完全解决问题!

那么作为前端,我们能做些什么?

劫持对策

  1. 302跳转或劫持为只含跳转代码的内容
    无解,因为不能载入我们的页面

  2. js注入,以document.write/document.writeln方式插入恶意JS文件
    简单粗暴,不太优雅,却有效,将document.write重写为空函数

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    var oriDocwrite = document.write;
    var docWrite = function (str) {
    if (oriDocwrite.apply) {
    oriDocwrite.apply(document, arguments);
    } else {
    oriDocwrite(str);
    }
    };
    document.write = function (str) {
    //这里可记LOG用于统计
    }
  3. 对于iframe的情况,要检测非常简单,只需要比较self和top是否相同。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <style>
    html{
    display: none;
    }
    </style>
    <script>
    if( self == top ) {
    document.documentElement.style.display = 'block' ;
    } else {
    top.location = self.location ;
    }
    </script>
  4. 更多视具体情况而定

主动探测是否存在劫持可能性

  • 监控插入页面的JS文件
  1. 在页面加载完成后,按某种策略(如散列在小范围定次定量定节奏)遍历DOM中的Script标签
  2. 利用MutationObserver(参见: 《JavaScript 标准参考教程》阮一峰 )监视DOM变动。

劫持始终“野火烧不尽”,祈祷互联网世界和平。

参考文献:

【1】 【HTTP劫持和DNS劫持】腾讯的实际业务分析
【2】再谈DNS劫持等恶意行为
【3】从运营商小广告到HTTPS