文档章节

关于互联网流量劫持分析及可选的解决方案

大数据之路
 大数据之路
发布于 2016/02/12 23:59
字数 4037
阅读 2225
收藏 30

1、何为流量劫持

前不久小米等六家互联网公司发表联合声明,呼吁运营商打击流量劫持。流量劫持最直观的表现,就是网页上被插入了一些乱七八糟的广告/弹窗之类的内容或者网址被无辜跳转,多了推广尾巴。比如下面这种:

inter

页面的右下角被插入了广告。

流量劫持总体来说属于中间人攻击(Man-in-the-Middle Attack,MITM)的一种,本质上攻击者在通信两端之间对通信内容进行嗅探和篡改,以达到插入数据和获取关键信息的目的。目前互联网上发生的流量劫持基本是两种手段来实现的:

  • 域名劫持:通过劫持掉域名的DNS解析结果,将HTTP请求劫持到特定IP上,使得客户端和攻击者的服务器建立TCP连接,而非和目标服务器直接连接,这样攻击者就可以对内容进行窃取或篡改。在极端的情况下甚至攻击者可能伪造目标网站页面进行钓鱼攻击。一般而言,用户上网的DNS服务器都是运营商分配的,所以,在这个节点上,运营商可以为所欲为。例如,访问http://jiankang.qq.com/index.html,正常DNS应该返回腾讯的ip,而DNS劫持后,会返回一个运营商的中间服务器ip。访问该服务器会一致性的返回302,让用户浏览器跳转到预处理好的带广告的网页,在该网页中再通过iframe打开用户原来访问的地址。

  • HTTP劫持/直接流量修改:在数据通路上对页面进行固定的内容插入,比如广告弹窗等。在这种情况下,虽然客户端和服务器是直接建立的连接,但是数据内容依然可能遭到野蛮破坏。例如在运营商的路由器节点上,设置协议检测,一旦发现是HTTP请求,而且是html类型请求,则拦截处理。后续做法往往分为2种,1种是类似DNS劫持返回302让用户浏览器跳转到另外的地址,还有1种是在服务器返回的HTML数据中插入js或dom节点(广告)。

能够实施流量劫持的根本原因,是HTTP协议没有办法对通信对方的身份进行校验以及对数据完整性进行校验。如果能解决这个问题,则流量劫持将无法轻易发生。

关于流量劫持的更多危害案例,可以参考:如何看待小米等联合声明:呼吁运营商严格打击流量劫持?

2、如何防止劫持:主动防御型

2.1 HTTPS防止劫持

p2367211

HTTPS,是HTTP over SSL的意思,提到HTTPS就不得不先简单描述一下SSL/TLS协议。SSL协议是Netscape在1995年首次提出的用于解决传输层安全问题的网络协议,其核心是基于公钥密码学理论实现了对服务器身份认证、数据的私密性保护以及对数据完整性的校验等功能。1999年IETF将SSL 3.0标准化,是为TLS 1.0版本,目前TLS协议的最新版本是1.2版本,TLS 1.3标准正在制定中。为了方便,下文将SSL/TLS协议都简称为SSL协议。

SSL协议在HTTP请求开始之前增加了握手的阶段,其粗略流程如下图所示:

https_1

  • 在SSL握手阶段,客户端浏览器会认证服务器的身份,这是通过“证书”来实现的,证书由证书权威(CA)为某个域名签发,可以理解为网站的身份证件,客户端需要对这个证件进行认证,需要确定该证书是否属于目标网站并确认证书本身是否有效。最后在握手阶段,通信的双方还会协商出一个用于加密和解密的会话密钥。

  • SSL握手阶段结束之后,服务器和客户端使用协商出的会话密钥对交互的数据进行加密/解密操作,对于HTTP协议来说,就是将HTTP请求和应答经过加密之后再发送到网络上。

由此可见,因为SSL协议提供了对服务器的身份认证,所以DNS劫持导致连接错误服务器的情况将会被发现进而终止连接,最终导致DNS挟持攻击无法实现。此外SSL协议还提供数据的加密和完整性校验,这就解决了关键信息被嗅探以及数据内容被修改的可能。

但是https也不是如此完美,虽然https解决了诸多安全问题,但是对性能也有着比较大的影响。一是用户要从http跳转到https,并且要多几次TLS的握手,这会消耗一定的时间;二是服务器的压力也会增加。除此之外如果使用全站的https,所有页面里面的嵌入资源都要改成https,APP的程序也要进行相应的修改,CDN的所有节点也必须都支持https并且导入证书。所以全站https并不是一件容易的事情,国外的Google、Facebook、Twitter早已支持全站https,但目前国内大多数公司都没有采用全站https的方式,微信算是一个,前段时间百度表示已经支持全站的https了,前段时间我试了一下,百度主站在pc端和移动端都已经可以自动跳转到https了,但是近期发现移动端又恢复成http了,可能是考虑访问体验问题。由此可见全站https应该是未来互联网的趋势。

2.2 绕过运营商localDNS,使用公共的DNS

让用户不使用运营商的local DNS改用114DNS,114DNS是国内最大的中立缓存DNS。推动用户自己手工去改DNS显然是不可行的,用户10个有9个都不知道DNS是啥。那如何去让用户不使用运营商的local DNS呢?po主在腾讯的一个工程师的博客里面看到有这么一段话:“如何在用户侧构造域名请求:对于PC端的客户端来说,构造一个标准的DNS请求包并不算什么难事。但在移动端要向一个指定的LocalDNS上发送标准的DNS请求包,而且要兼容各种iOS和android的版本的话,技术上是可行的,只是兼容的成本会很高。”po主认为这种方式暂且不谈技术上是否可行,最大的问题应该是无法确保公共DNS的稳定性。一旦公共的DNS遭到攻击,将会导致全国性的故障,所以一定需要一个冗余的方案,就是当公共DNS挂了后,可以去向运营商的local dns去请求。

2.3 抛弃域名访问方式,直接进行通过IP访问

这种解决思路,po主了解的有两种方式,第一种是httpdns,这种应该是目前DNS防劫持的主流方式,但是网上相关的介绍非常少,从腾讯员工的博客以及阿里朋友给的内部资料上看,现在腾讯和阿里都在用这种方式。另一种是网宿的MAA解决方案。两者的原理大同小异,都是为移动APP而量身定制的。

httpdns的原理大致就是在移动客户端中加入一个域名解析的模块,客户端通过http的方式向企业的流量调度服务器请求ip,此时流量调度服务器会回根据用户所在位置给用户一个最优的ip。客户端在获取ip后直接用此ip来访问所需站点资源。

这种方式看着确实很完美,但是对于一般的企业来说想要实现是一件极具挑战的事情。

      1、客户端需要进行一定的开发来满足客户端的httpdns的请求;

      2、针对这个流量调度服务器需要自己开发一套所有节点的IP地址库以及测速系统,才可以保证将用户引导的访问最快的IDC节点上,并且对于使用了CDN加速的域名来说,这个IP地址库是不可控的。

      3、如何保证高可用性以及不同运营商的用户访问到同一个HttpDNS的服务IP,用户的访问延迟?腾讯的做法是:HttpDNS通过接入了腾讯公网交换平台的BGP Anycast网络,与全国多个主流运营商建立了BGP互联,保证了这些运营商的用户能够快速地访问到HttpDNS服务;另外HttpDNS在多个数据中心进行了部署,任意一个节点发生故障时均能无缝切换到备份节点,保证用户解析正常。

      所以说httpdns是一个好的解决方案,但是用起来并不容易,而其投入产出比也只有在一些巨型的互联网公司身上才能体现出来。

       再来说说网宿的MAA的解决方案,po主觉得和httpdns比较类似,前提是这个域名要使用网宿的CDN加速。网宿的MAA方案其实就是帮一般企业来解决上面httpdns的三点难点。


      1、客户端插入网宿研发的SDK,向其鉴权服务器请求ip;

      2、网宿的鉴权服务器类似于httpdns中的流量调度服务器,因为CDN厂商本来就要负责调度CDN节点的资源,所以这点对他们来说很容易;

      3、如何保证高可用性以及不同运营商的用户访问到鉴权的服务器,用户的访问延迟?这点网宿的资料里面没有提到,po主个人猜测问题应该不大,因为对于一个CDN加速的域名来说,用户本来就是要去网宿的鉴权的服务器的,而对于一个提供CDN服务的厂商来说,鉴权的服务器的高可用肯定是要做好的。

      (以上绝对非软文,po主觉得是个很好的解决思路,表示要向网宿征收广告费啊!!!)

       但是网宿的这个解决方案同样存在问题:

       1、插入SDK的方式很多大企业可能无法接受

       2、只能用于网宿加速的域名,其他厂商的CDN节点的ip信息网宿不可控,这样可能会被一个厂商绑架。

总的来说主动防御型的解决方案总体上看虽然可以从根本上解决劫持问题,但是成本高,研发周期长,适合超大的互联网公司,但未必适合所有企业。

3、如何防止劫持:被动监测型

       被动监测型主要是通过采集用户访问站点的网络参数的方式来判断是否遭到劫持,比如通过采集用户访问站点的ip地址来和我们真实站点以及CDN节点的ip地址进行比对,判断是否遭到DNS劫持,或者通过采集用户访问的URL和真实站点的URL进行比对,判断是否遭到链路劫持。在PC时代对于被动监测型一般就是真机模拟这一种方式,但是在随着移动互联网的快速发展,针对于移动APP出现了一种插入SDK来监测的方式,这两种方式采用的技术手段完全不同,也各有利弊。这种小规模的检测还行,实际应用中,基本还是以方案 2 为主。

例如这里先对外网做检测,上报被劫持的情况:

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

(注:事后发现这个url检查不够严谨,虽然劫持的情况都能发现,但也把产品原有的一些正常插入做劫持误报了。例如<a href="http://jiankang.qq.com" data-id="1">,不过这个是小细节,把正则表达式完善一下就ok了)

比如还可以针对注入dom节点的情况,初始化时做检查,而且后续dom注入也做检查。可以检查dom中是否含有白名单以外的http链接,如果有,就可以判定为http劫持。

4、防劫持的实际案例与小技巧

4.1 重写 document.write

一般来说,工程师做低成本的防御需要先找到运营商设置的劫持规律。比如这个 case 中查到是运营商采用 document.write 改写了页面内容或者 dom 节点,那么我们可以简单粗暴的将document.write重写为空函数:

var oldDocwrite = document.write,newDocwrite = function(str){};
if(oldDocwrite.apply){
    hao360.docWrite = function(str){
        oldDocwrite.apply(document,arguments);
    }
}else{
    hao360.docWrite = oldDocwrite;
}
document.write = newDocwrite;

显然这种方案有些太不优雅,但却也很有效。

第二个方案是豆瓣 http://www.douban.com/js/do.js 尾部用到的白名单过滤方案:

// @TODO 临时应对劫持 by dexteryy
var _write = _doc.write,
_white_list = {
    'douban.com': 1,
    'douban.fm': 1,
    'google.com': 1,
    'google-analytics.com': 1,
    'googleadservices.com': 1
},
// 统计劫持情况
_hijack_stat = function(reason, env){
    var img = new Image();
    img.onload = function(){};
    img.src = "http://www.douban.com/j/except_report?kind=ra022&reason="
        + encodeURIComponent(reason)
        + "&environment=" + encodeURIComponent(env);
},
_RE_SCRIPTS = /<script.*?src\=["']?([^"'\s>]+)/ig,
_RE_DOMAIN = /(.+?)\.([^\/]+).+/;
_doc.write = function(str){
    try {
        var s, safes = [], unkowns = [];
        while (s = _RE_SCRIPTS.exec(str)) {
            if (_white_list[(_RE_DOMAIN.exec(s) || [])[2]]) {
                safes.push(s);
            } else {
                unkowns.push(s);
            }
        }
        if (unkowns.length > 0) {
            _hijack_stat([unkowns[0], safes[0] || ""].join("~_~"), location.href);
        }
        try {
          _write.call(this, str);
        } catch (ex) {
          _write(str);
        }
    } catch (ex) {
        _write(str);
        _hijack_stat(ex.name + ":" + ex.message, location.href);
    }
};

上两个方案可视项目情况而定,各有利弊。

但是如果运营商换个方案,不采取document.write,那真就要很难斗了。当然如果无耻的DNS劫持始终跟着流量入口页的对策升级方案,那咱们还是洗洗睡吧。

4.2 更过分的整站劫持

另外说一句一些地方的小运营商,如四川南充某运营商所管辖的这部分地域,直接将hao.360.cn指向自己的导航页面了,虽然样子还是定期缓存360导航的页面,但其中内容却已被改动多半。对于这些的确的用户反馈,我们只能表示无奈,且也尝试付诸于法律手段。

4.3 结语

所以结论就是运营商是用户的“最后一公里”,我们只能尽力而为也就是了。

Refer:

[1] 使用HTTPS防止流量劫持

https://yq.aliyun.com/articles/2666

[2] 关于互联网流量劫持分析及可选的解决方案

http://www.jianshu.com/p/eff9553c8b64#

[3] 关于启用 HTTPS 的一些经验分享(一)

https://imququ.com/post/sth-about-switch-to-https.html

[4] 关于启用 HTTPS 的一些经验分享(二)

https://imququ.com/post/sth-about-switch-to-https-2.html

[5] 运营商DNS劫持的那些事儿 作者:irideas

http://bit.ly/1PrpIa6

[6] 【HTTP劫持和DNS劫持】腾讯的实际业务分析

http://www.cnblogs.com/kenkofox/p/4919668.html

[7] 疯狂的淘宝客:一次搜索引擎流量劫持事件分析

http://bit.ly/1LkZmmd

[8] dig与dns基本理论——解析和缓存

http://www.juvenxu.com/2014/08/04/dig-and-basic-dns-resolving-and-cache/

[9] 详解https是如何确保安全的?

http://bit.ly/260gPgh

本文转载自:https://yq.aliyun.com/articles/2666

大数据之路
粉丝 1605
博文 514
码字总数 334022
作品 0
武汉
架构师
私信 提问
吓skr人了!网站莫名跳转,真相竟然是这样……

伴随着互联网发展,大家都习惯了在浏览器地址里输入HTTP格式的网址。1989年,世界上第一个HTTP(HyperText Transfer Protocol超文本传输协议)诞生,早期HTTP设计出来只是为了考虑到用户的便...

亚洲诚信
2018/08/01
51
0
在互联网你的请求是如何被引导、劫持的?

大多数的引导和劫持都是到cache设备上的,做cache有诸多好处,比如对于运营商而言可以节省网间流量(省钱)、提高用户体验(静态内容、视频等加速),对于网站主通过CDN做了cache后可以提高用...

愚人乙
2016/07/22
0
0
阿里云Web应用防火墙接入案例分享之http流量劫持

一、概述   在日常使用阿里云Web应用防火墙的用户中,会出现一些对WAF上域名发起http请求时被流量劫持的情况,通过对这些问题案例的梳理,总结了相关方案供大家参考。 二、案例 2.1 案例一...

游客hauedqe6g6xy6
06/18
0
0
CDN市场洗牌期倒计时 京东云凭什么留到最后?

  【IT168 云计算】近两年,视频直播业务需求爆发式增长,众多云服务商纷纷跻身CDN市场,颠覆了CDN行业多年传统CDN寡头垄断的市场格局。   随着CDN市场进入“颠覆整合期”,从卖方市场迅...

it168网站
2017/08/17
0
0
NSA泄露文件深度分析:NSA与运营商的故事

只是简单看了工具包中的EXP,并在网上关注了一下国外对该工具包的反响。发现该EXP经过一定的修改,能完全适应2016年最新版本的系统固件,一个如此久远的EXP能做到如此实属不易,看来NSA的代码...

燕儿199606
2017/08/01
0
0

没有更多内容

加载失败,请刷新页面

加载更多

springboot集成elasticsearch-rest-high-level-client的坑

我使用的是Elasticsearch7.2.0,由于官网上推荐使用elasticsearch-rest-high-level-client端集成在springboot所以尝试爬坑。 首先直接引入官网的配置文件 <dependency> <grou...

MuzzyXu
27分钟前
5
0
ECMAScript运算符之《等性运算符》

等性运算符一般用在判断两个变量是否相等的运算。在处理原始值时,这种运算相当简单,涉及对象,任务就稍有点复杂。 性运算符分: 1、等号和非等号用于处理原始值 2、全等号和非全等号用于处...

专注的阿熊
30分钟前
4
0
ssh-keygen -t rsa -C "注释内容,一般为邮件地址",生成的公钥后面会带上注释,这个注释有什么用处呢?

ssh-keygen -t rsa -C "注释内容,一般为邮件地址",生成的公钥后面会带上注释,这个注释有什么用处呢? donhui 发布于 2015/11/12 16:47 阅读 5K+ 收藏 0 答案 1 补充话题 OpenSSH 为什么8...

linjin200
32分钟前
4
0
Proxy用法——让我们创建一个API代理器

什么是Java Proxy? MDN对Proxy 的定义是: Proxy对象用于定义基本操作的自定义行为(如属性查找、赋值、枚举、函数调用等)。 通俗的将,Proxy对象是目标对象的一个代理器,任何对目标对象的...

AiChinaTech
35分钟前
5
0
Nginx--面试基础必会

文章原创于公众号:程序猿周先森。本平台不定时更新,喜欢我的文章,欢迎关注我的微信公众号。 最近一直在更新关于Nginx的系列文章,终于将Nginx的几个关键知识点讲的差不多了。本篇作为Ngi...

程序猿周先森
37分钟前
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部