一直以来,电信通过HTTP劫持推送广告的方式已经存在了很多年了,这种手段至今并未停止。这种手段月光博客曾经有多次曝光,见《电信级的网络弹出广告》、《获取了电信恶意弹出广告的罪证》和《谁控制了我们的浏览器?》。虽然HTTP本身的不安全性导致有路由器控制权限的人(比如电信运营商)可以获得没有使用HTTPS登录认证的网站的注册用户的密码,但一开始我并不认为电信运营商会犯触犯法律的风险进行实施。但现在我发现我错了。
现在有证据显示电信运营商非但获取没有加密的HTTP登录的用户名和密码,还会通过HTTP劫持的手段获取通过RSA加密的用户名和密码。信息来源是国内最大的最权威的漏洞报告平台之一wooyun:链接1、链接2。
正如文中所说,国内某邮件服务商在登录入口处将用户输入的帐号和密码通过RSA加密后才会发送到网络上,通过截取网络数据包的方式已经无法对用户输入的 密码进行破解了。但由于HTTP本身并没有加密功能,所以RSA的程序必须由邮件服务商以JavaScript的方式进行提供,而登录入口的HTML和所 有的JavaScript会通过HTTP发送到用户的浏览器上。而正是由于HTTP的不安全性,导致电信运营商可以在HTML中插入附加的 JavaScript代码,在对密码进行RSA加密之前将密码以明文形式发送到网络上。至此,密码已经可以通过抓取网络数据包的方式进行截取了。
这种手段并非DNS级的域名劫持。如果是域名劫持,那么用户访问的也就不是邮件服务商的服务器,而是第三方的服务器了。如果要保证用户可以正常登录邮 箱,那么第三方服务器就必须将用户浏览器的请求转发到邮件服务商,这样邮件服务商将会看到大量用户通过同一个或少数几个IP地址进行登录,很快就会发现问 题。所以只有控制路由器进行TCP级别的HTTP劫持(仿冒邮件服务商的IP发送附加的JavaScript的数据包)才能做到神不知鬼不觉(虽然出了 BUG导致曝光了,但如果没有BUG说不定到现在仍旧无人察觉)。
联想到《破解Google Gmail的https新思路》 中所说的情况,电信运营商和国内的CA机构受到某些部门的指使进行实施,对SSL不了解的人完全可以做到神不知鬼不觉地破解用户的密码。如果是DNS劫持 还可以通过多种手段进行反劫持,但如果通过类似HTTP劫持的这种IP仿冒的技术呢?据我观察,CNNIC根证书并未在各大浏览器中已被移除,所以关注于 安全的朋友还是需要手动进行处理。也正如wooyun的文中所说,看到国内CA随便签署的证书,一定要保存下来提交给各大浏览器厂家,国内的中级CA还有 很多。
题外话:虽然全球的网络自由在恶化,但并不代表我们就可以放弃追求网络自由。
链路劫持攻击一二三
博文作者:lake2 [ TSRC ]
发布日期:2012-11-09
阅读次数:35724
博文内容:
随着应用安全的发展,大家都比较关注应用安全漏洞,其实在应用层之下的传输层也有很多安全风险,而且这些安全风险正在被广泛利用。比如今天要给大家介绍的TCP链路劫持攻击。
TCP链路劫持其实就是指网络链路上侦听、伪造TCP包,达到控制目标网络链路的行为。最常见的就是某些设备实现的对非法站点的访问拦截,以及一些地区运营商的网页植入广告行为。
因为广域网的链路劫持影响面大,一般会影响一个地区甚至是全国,所以本文重点讨论广域网的TCP链路劫持,局域网的劫持如ARP攻击不在讨论范围。
目前发现的TCP链路劫持攻击一般有两种形式:中断访问型(分为单向发包和双向发包)和替换页面型。
中断访问型常见于阻止用户访问某些网站,如某些设备禁止用户访问某些站点、某地运营商的禁止ADSL多终端上网功能。其原理就是伪造服务端给用户发RST包阻止TCP连接的建立(单向发包)。某些设备做得比较狠,在冒充服务端给用户发RST包的同时也冒充用户给服务端发RST包(双向发包)。
替换页面型常见于运营商植入广告,也有篡改正常网页进行SEO、骗流量的。笔者见过最恶劣的莫过于钓鱼,如2011年出现过的Gmail钓鱼事件以及一些不能告诉你的钓鱼事件。原理也简单,就是在一个HTTP请求后伪造服务端的HTTP响应给客户端。
如下图所示就是一次典型的TCP链路劫持替换页面,我们可以看到,TCP三次握手完成后,HTTP请求包发送后,客户端收到两个HTTP响应包,因为伪造的第一个包(10号)先到,所以第二个正常的HTTP响应包(13号)被客户端忽略了。很明显,在网络上有一个设备,侦听整个会话,当匹配某个特征就抢先发包劫持会话。
这些利用链路劫持进行的弹窗广告、“技术问题”产生的误拦截、植入代码不慎将页面弄乱、甚至是钓鱼等将会损害用户利益。笔者跟链路劫持的“不解之缘”就因此而起。
要解决链路劫持先要搞清楚是否是链路劫持,如是则出问题的大概位置在哪里。链路劫持是区域性的,一般来讲某地区用户集中投诉,就可以联系用户调查了。用户往往不懂Wireshark抓包,还要远程协助,如果网速慢就是悲剧……各种心酸且按下不表。
抓到可疑包之后关注两个关键点:TTL值和IP Id(Identification)。根据实际观测,伪造的TCP包的TTL值和Id是不符合逻辑的。
比如下图,真实包的TTL是53,Id是按顺序自增的,而伪造的包的TTL是64,Id始终是0。还有,笔者也见过某地运营商禁止ADSL多终端上网功能会伪造Id值恒为8888的RST包。
通过伪造的TTL值就可以大致定位侦听设备的位置。利用伪造的数据包的TTL值加上当时用户的路由即可定位:数据包每经过一个路由TTL值就会减一,我们找到假的包,看他的TTL(一般初始发出的TTL是256或128或64)减了多少,反推回去就找到出问题的位置了。
刚刚那个截图,伪造的的TCP包TTL值是64,也就是可以推测出链路劫持就发生在局域网内。的确如此,这个case是一个路由器软件进行链路劫持的案例。
有个问题,如果攻击者聪明一些,伪造包定制一个TTL值,就会导致我们难以精确定位。比如某些设备会发三次RST包,每次的TTL都不一样。注意,我说的“难以定位”并非“不能定位”,还是有办法的,需要动动脑子。
坏人是很多的,不能每次都被动等待用户投诉,如何主动发现链路劫持呢?
客户端访问目标站点的时候,同一个TCP会话的TTL值发生较大变动,就可以判定为疑似劫持。以下python代码就是一个利用Scapy检测TCP链路劫持的示例:
#!/bin/python # # import sys from scapy.all import * conf.verb=0 print "TCP Hijacking Delector by lake2" print "[+] Sniffing ...." ip_arr = {} while 1: a=sniff( filter="tcp and src host not 10.26.234.44", count=50) for b in a: ip_src = b.sprintf(r"%IP.src%") ip_ttl = b.sprintf(r"%IP.ttl%") if ip_arr.has_key(ip_src): c = int(ip_ttl) - int(ip_arr[ip_src]) if abs(c) > 4: print ip_src + " has been hijacking !!! debug info : " + str(ip_ttl) + " <-> " + str(ip_arr[ip_src]) else: ip_arr[ip_src] = ip_ttl print "=>"
检测到某些设备拦截笔者在Google搜索敏感关键字的链路劫持:
双向RST的情况,部署在机房的IDS也可以发现端倪。
如果是替换页面型攻击,页面hash或者HTML元素个数会有异常,这里也可以作为一个检测点。
防范链路劫持就比较困难,毕竟攻击者控制着网络链路。不过并非不可能。
一是网站全程使用SSL。
再一个就是在客户端或(和)服务器丢弃伪造的TCP包。比如前面说到的单向中断访问型攻击,就可以丢弃包含伪造特征的TCP包(如Id为0或8888)。某些项目就是利用客户端、服务端同时丢弃的方式来翻墙的。
最后,我们可以看到广域网一点都不安全,所以敏感信息传输一定要加密,还要高强度加密;高端网页最好有个校验机制;自动升级的程序也一定要校验文件签名。
转自:http://security.tencent.com/index.php/blog/msg/10