• 网络安全之DNS劫持和HTTP劫持
  • 专心滴打铁 发表于 2015/10/29 12:47:00 | 分类标签: DNS劫持 HTTP劫持技术
  •      简单介绍一下HTTP劫持和DNS劫持的概念,也就是运营商通过某些方式篡改了用户正常访问的网页,插入广告或者其他一些杂七杂八的东西。
     
        首先对运营商的劫持行为做一些分析,他们的目的无非就是赚钱,而赚钱的方式有两种:
        1、对正常网站加入额外的广告,这包括网页内浮层或弹出广告窗口;
        2、针对一些广告联盟或带推广链接的网站,加入推广尾巴。例如普通访问百度首页,被前置跳转为http://www.baidu.com/?tn=90509114_hao_pg 
     
        在具体的做法上,一般分为DNS劫持和HTTP劫持。

        DNS劫持:

        一般而言,用户上网的DNS服务器都是运营商分配的,所以,在这个节点上,运营商可以为所欲为。
        例如,访问http://jiankang.qq.com/index.html,正常DNS应该返回腾讯的ip,而DNS劫持后,会返回一个运营商的中间服务器ip。访问该服务器会一致性的返回302,让用户浏览器跳转到预处理好的带广告的网页,在该网页中再通过iframe打开用户原来访问的地址。

        HTTP劫持:

        在运营商的路由器节点上,设置协议检测,一旦发现是HTTP请求,而且是html类型请求,则拦截处理。后续做法往往分为2种,1种是类似DNS劫持返回302让用户浏览器跳转到另外的地址,还有1种是在服务器返回的HTML数据中插入js或dom节点(广告)。
     
     
        在用户角度,这些劫持的表现分为:
        1、网址被无辜跳转,多了推广尾巴;
        2、页面出现额外的广告(iframe模式或者直接同页面插入了dom节点)。
     
        处理办法:
        1、先对外网做检测,上报被劫持的情况。
                对于我这个业务而言,加推广尾巴没意义,那么就剩下植入广告的问题了。页面广告可能通过iframe方式,也可以通过dom节点方式,需要在首页检查这两种情况。
    1. window.addEventListener('DOMNodeInserted', checkDivHijack);      
    2. function checkDivHijack(e) {  
    3.         var html = e ? (e.srcElement.outerHTML || e.srcElement.wholeText) : $('html').html();  
    4.         var reg = /http:\/\/([^\/]+)\//g;  
    5.         var urlList = html.match(reg);  
    6.         if (!urlList || urlList.length == 0) {  
    7.             return;  
    8.         }  
    9.         reg = /^http:\/\/(.*\.qq\.com|.*\.gtimg\.cn|.*\.qlogo\.cn|.*\.qpic\.cn|.*\.wanggou\.com)\/$/;  
    10.         var hijack = false;  
    11.         for (var i = 0; i < urlList.length; i++) {  
    12.             if (!reg.test(urlList[i])) {  
    13.                 hijack = true;  
    14.                 break;  
    15.             }  
    16.         }  
    17. }  

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

     
        2、针对被iframe加载的情况,需要先找到运营商设置的劫持规律。
                在iframe中的网页能正常打开,而不是又被拦截加iframe,可能是因为请求的url上或cookie上运营商做了标记。我们可以利用这个规则,躲过劫持。
     
        3、针对注入dom节点的情况,初始化时做检查,而且后续dom注入也做检查。可以检查dom中是否含有白名单以外的http链接,如果有,就可以判定为http劫持。
     
        4、在前端以外的处理办法还有

            a) 终端拦截所有返回包,判断ip来自黑名单(劫持的中间ip)则丢弃返回包。
                    这种做法的原因是,运营商劫持http请求后,并不是完全丢弃请求包,而是做了复制,一份继续发给目标服务器,另外一份做劫持处理直接返回302。因为这个302会比目标服务器的正常返回早得多,所以用户浏览器会只认第一个302,而丢弃后到的正常返回。
                    如果先把第一个302丢弃,等待后续正常返回,则问题解决。
            b) 终端拦截请求包,并拆包发送。
                    运营商一般判断是否劫持,通过判断是否HTTP请求。 一般只会检测TCP连接建立后的第一个数据包,如果其是一个完整的HTTP协议才会被标记;如果并非是一个完整的HTTP协议,由于无法得到足够多的劫持信息,所以并不会被标记为HTTP协议。 
                    所以,只要把请求包切得足够细,就能躲过一部分劫持(如果运营商学习“墙”大力气做多包拦截就没辙了)。
            
        5、当然,最终,根本解决办法是使用HTTPS,不过这个涉及到很多业务的修改,成本较高。如果劫持比例小,也许通过适当的补救做法会更好。
     
     
      来看看检测到的劫持情况:

    总体1500万pv的业务,一天竟然有100万的劫持上报,即使排除一半的误报,也代表说20个用户中,就接近有1个用户出现被劫持的情况。
    可见,各种小运营商(尤其是移动)的心是有多黑!胆子是有多大!
     
      各种劫持的手段都有:
      1、直接返回一个带广告的HTML;
      2、在原html中插入js,再通过js脚本安插广告;
      3、iframe展示原来正常网页。
     
      各种丑恶的嘴脸都被记录在案:
      
  • 请您注意

    ·自觉遵守:爱国、守法、自律、真实、文明的原则

    ·尊重网上道德,遵守《全国人大常委会关于维护互联网安全的决定》及中华人民共和国其他各项有关法律法规

    ·严禁发表危害国家安全,破坏民族团结、国家宗教政策和社会稳定,含侮辱、诽谤、教唆、淫秽等内容的作品

    ·承担一切因您的行为而直接或间接导致的民事或刑事法律责任

    ·您在编程中国社区新闻评论发表的作品,本网站有权在网站内保留、转载、引用或者删除

    ·参与本评论即表明您已经阅读并接受上述条款

  • 感谢本文作者
  • 作者头像
  • 昵称:专心滴打铁
  • 加入时间:2013/7/13 0:00:00
  • TA的签名
  • 这家伙很懒,虾米都没写
  • +进入TA的空间
  • 以下内容也很赞哦
分享按钮