上一篇文章,介绍了常见的流量劫持途径。然而无论用何种方式获得流量,只有加以利用才能发挥作用。
不同的劫持方式,获得的流量也有所差异。DNS 劫持,只能截获通过域名发起的流量,直接使用 IP 地址的通信则不受影响;CDN 入侵,只有浏览网页或下载时才有风险,其他场合则毫无问题;而网关被劫持,用户所有流量都难逃魔掌。
在本文中,我们通过技术原理,讲解如下问题:
为什么喜欢劫持网页?
只浏览不登陆就没事吗?
自动填写表单有风险吗?
离开劫持环境还受影响吗?
使用 HTTPS 能否避免劫持?
流量劫持能否控制我电脑?
为什么喜欢劫持网页?
理论上说,劫持到用户的流量数据,也就获得相应程序的网络通信。但在现实中,数据并不代表真实内容。一些重要的网络程序,都是私有的二进制协议,以 及各种加密方式。想通过流量来还原出用户的聊天信息、支付密码,几乎是不可能的。即使花费各种手段,破解出某个程序的通信协议,然而一旦程序升级改变了协 议格式,或许就前功尽弃了。因此,很难找到种一劳永逸的客户端劫持方案。
然而,并非所有程序都是客户端的。一种新兴的应用模式 —— WebApp,发展是如此之快,以至于超越客户端之势。在如今这个讲究跨平台、体验好,并有云端支持的年代,WebApp 越来越火热。各种应用纷纷移植成网页版,一些甚至替代了客户端。同时,也造就了流量劫持前所未有的势头。
WebApp,其本质仍是普通的网页而已。尽管网页技术在近些年里有了很大的发展,各种新功能一再增加,但其底层协议始终没有太大的改进 —— HTTP,一种使用了 20 多年古老协议。
在 HTTP 里,一切都是明文传输的,流量在途中可随心所欲的被控制。传统程序事先已下至本地,运行时只有通信流量;而在线使用的 WebApp,流量里既有通信数据,又有程序的界面和代码,劫持简直轻而易举。
上一篇也提到,如果在户外没有 3G 信号的地方钓鱼,无法将获得的流量转发到外网。然而,使用网页这一切就迎刃而解。我们完全可以在自己的设备上搭建一个站点,留住用户发起离线攻击。对于那些连上 WiFi 能自动弹网页的设备,那就更容易入侵了。
因此,劫持网页流量成了各路黑客们的钟爱,一种可在任意网页发起 XSS 的入侵方式。
下面,开始我们的攻防之旅。
只浏览不登陆就没事吗?
每当砖家出来提醒时,总免不了这么一句:公共场合尽量不登录账号。于是,大家就认为只看网页不登陆就平安无事了。
如果是公共的电脑,那也就无所谓;否则,自己的一些账号可能就倒霉了。
在自己的设备上,大家都会记住各种账号的登录状态,反正只有自己用,也没什么大不了的。然而,在被劫持的网络里,一切皆有可能发生。即使浏览再平常不过的网页,或许一个悄无声息的间谍脚本已暗藏其中,正偷偷访问你那登录着的网页,操控起你的账号了。
听起来似乎很玄乎吧,砖家似乎也没说已登录的账号会怎么样。难道随便一个网页,就能让各种账号被控制吗?
大家都知道,HTTP 是无状态的,不像传统协议有个『会话』之类的概念。各种账号的登录状态,只能依靠浏览器的 Cookie 来实现。因此,只要有了的 Cookie 也就获得了用户账号的使用权。
和传统 XSS 攻击不同,流量劫持可以得到任何通信数据,当然也包括那些受 HttpOnly 保护的 Cookie。攻击脚本只需对某个站点发起请求,黑客即可在中途劫持到传输的 Cookie 数据。如果同时发起众多站点,就能覆盖相当一部分目标了。
这种请求未必要真正访问一次页面,仅仅将 URL 作为图片加载,将目标站点的 Cookie 送出即可。
黑客得到 Cookie,即可在自己浏览器里还原出登录状态。尽管你确实没有登录操作,但那些已登录的却能出卖你。
防范措施:访问一些重要的网站,尽量不要记住登录状态,以免 Cookie 被泄露。不过,只要网站绑定了 Cookie 和 IP 段,这招的危害程度就大幅降低了,仅凭 HttpOnly 还是很不靠谱的。
自动填写表单有风险吗?
使用上面的方法获得 Cookie,即使能控制账号,但其密码仍无法得知,随时都有可能失去控制权。
不过,一些用户有让浏览器自动保存密码的习惯。通过这点,我们是否能套出记住的密码来呢?
分析下浏览器是如何自动填写页面表单的。其实很简单,浏览器发现页面 URL 和表单名匹配记录里的,就自动填上了。
要是在流量可控的网络里,剥离页面所有内容只剩表单,又会如何?
保存着的密码仍能自动填上,并且可被脚本访问到!
如果我们在用户访问的页面里,创建大量的隐藏框架页,即可尝试获取各种网站保存着的账号了。(如今 Chrome 框架页已经不会自动填写了。具体实现和浏览器有关)。
然而,即使框架页不自动填写,但主页面总得保留该功能吧。如果发现用户某个打开着的网页很久没有交互了,可悄悄跳转到如上那样的纯表单页,无论能否获取数据,都将继续跳转,一个接一个的尝试。。。直到用户切回窗口,再恢复到原先那个页面。
由于泄露的是明文的账号和密码,即使数量不多,也能通过社工获取到用户的更多信息,最终导致更严重的泄露。
防范措施:所以无论是 Cookie 记住登录,还是浏览器自动填表,重要的账号都应慎用。
浏览器的自动填表也应增加些安全策略,例如必须有用户的交互才开始填写,规定的时间里只能填有限次。
离开劫持环境还受影响吗?
或许你在想,网络再怎么不安全,离开之后就应该没事了吧。
有时在公共场合赶上免费的 WiFi,打开网页看一会新闻,是常有的事。这么短的时间里能有多大的事。不过在入侵脚本面前,一小会和长久并没太大区别。机会只要出现了,无论多么短暂都能渗透。
如果只看重眼前利益,这种短暂的入侵并没多少利用价值;但若放远目光,能让攻击在今后发起,那就不再局限于时间和空间了。因此,我们需要一个时光机,让入侵脚本穿越到用户未来的时空运行。
若用传统 XSS 的思维,这几乎无法实现。但在流量劫持面前,一切皆有可能 —— 因为我们能控制任意流量!
HTTP 缓存投毒
上一篇文章提到,但凡有缓存的地方都是大有可为的。显然,对于有着复杂的 HTTP 缓存系统来说,存在缺陷是在所难免了。这种简单的纯文本协议,几乎没有一种签名机制,来验证内容的真实性。即使页面被篡改了,浏览器也完全无法得知,甚至连同注入的脚本也一块缓存起来。
于是,我们可以将『缓存投毒』的概念,引入 HTTP 协议里。但凡具备可执行的资源,都可以通过预加载带毒的版本,将其提前缓存起来。
为了将缓存的有效期发挥到极致,我们事先在各大网站上,找出一些过期时间长、很久没有修改的资源,评估其未来变化不大的可能。
当用户打开任意一个 HTTP 网页时,注入的 XSS 代码开始预加载这些资源。由于一切流量都在控制之中,我们可以完全不走代理,而是返回自己的攻击脚本。
用户浏览器收到回复后,就将其一一缓存起来了。我们可以事先收集大量的资源地址,让用户在线的时间里,尽可能多的缓存受到感染。
未来,用户访问引用了这些资源的网站时,入侵脚本将穿越时空,从沉睡中唤醒。
只要用户不清空缓存,这些被感染的脚本始终附着在浏览器缓存里,直到用户强制刷新页面时或许才能解脱。更多细节可参考这里。
离线储存投毒
不过,有些网站使用的都是很短的缓存,上述的入侵方式似乎就无能为力了。不过,HTML5 时代带来了一项新的缓存技术 —— 离线储存。由于它没有过期时间,因此适用于任意网页的投毒!
类似的,当用户触发了我们的注入脚本之后,我们创建一个隐形的框架页,加载被感染的网页。同样,通过流量劫持,我们返回一个简单的页面,里面包含一个带有 manifest 属性的 HTML 文档,以及后期运行的脚本。
由于通过隐藏框架访问了这个页面,用户并不知情,但尽职的浏览器却将其缓存起来。
未来,用户打开被感染的网页时,浏览器直接从离线储存里取出,其中布置的脚本因此触发。
由于是个空白页面,因此需要填充上真实的网站内容。最简单的方法,就是嵌套一个原页面的框架,并在 URL 里加上随机数,确保是最新的在线内容。
因为嵌套的是同域框架,最终仍能被入侵脚本所控制。
不过,离线存储投毒的后期影响会小一些。未来用户在安全的网络里打开页面时,虽然能立即显示之前缓存的页面,但同时也会尝试访问 .appcache 文件。由于这个文件大多都不存在,因此浏览器很可能删除掉离线数据,导致之后的访问不再使用离线储存。
因此理论上说只有一次的触发机会,但它没有过期时间,适用于任意 HTTP 页面投毒。
防范措施:在不安全的场合,尽量使用『隐身模式』浏览网页。例如 Chrome 里按 Ctrl+Shift+N 就能调出,可将自己处于隔离的沙盒里。
FireFox 浏览器存储离线文件时,会有用户交互提示,提醒用户是否有这必要。
也许不久后,框架页面不再被离线储存所接受,新标准随时都有可能改变。但 HTTP 缓存投毒是协议栈的缺陷,因此很难防范,下一篇会发现实际入侵效果非常理想。
使用 HTTPS 能否避免劫持?
如果从密码学的角度来说,使用了 SSL 加密的数据确实难以破解,更不用谈修改了。
然而,惹不起但总躲得起吧。虽然无法破解,但流量仍掌握在自己手中,走哪条路还是由我说的算,完全可以绕过你。
偷换证书
不同于简单的 HTTP 代理,HTTPS 服务需要一个权威机构认定的证书才算有效。自己随便签发的证书,显然是没有说服力的,HTTPS 客户端因此会质疑。
在过去,这并不怎么影响使用过程,无非弹出一个无效的证书之类的提示框。大多用户并不明白是什么情况,就点了继续,导致允许了黑客的伪证书,HTTPS 流量因此遭到劫持。
在经历越来越多的入侵事件之后,人们逐渐意识到,不能再轻易的让用户接受不信任的证书了。如今,主流浏览器对此都会给予严重的警告提示,避免用户进入伪安全站点。
如果重要的账户网站遇到这种情况,无论如何都不该继续,否则大门钥匙或许就落入黑客之手。
因此,这种偷换证书的劫持,在安全意识越来越高的今天,很难再发挥实效了。我们需要一个更隐蔽的方式来躲开加密数据。
过滤 HTTPS 跳转
事实上,在 PC 端上网很少有直接进入 HTTPS 网站的。例如支付宝网站,大多是从淘宝跳转过来,而淘宝使用的仍是不安全的 HTTP 协议。如果在淘宝网的页面里注入 XSS,屏蔽对 HTTPS 的页面访问,用 HTTP 取而代之,那么用户也就永远无法进入安全站点了。
尽管地址栏里没有出现 HTTPS 的字样,但域名看起来也是正确的,大多用户都会认为不是钓鱼网站,因此也就忽视了。
因此,只要入口页是不安全的,那么之后的页面再安全也无济于事。
当然也有一些用户通过输网址访问的,他们输入了 www.alipaly.com
就敲回车进入了。然而,浏览器并不知道这是一个 HTTPS 的站点,于是使用默认的 HTTP 去访问。不过这个 HTTP 版的支付宝的确也存在,其唯一功能就是重定向到自己 HTTPS 站点上。
劫持流量的中间人一旦发现有重定向到 HTTPS 站点的,显然不愿意让用户走这条不受自己控制的路。于是拦下重定向的命令,自己去获取重定向后的站点内容,然后再回复给用户。于是,用户始终都是在 HTTP 站点上访问,自然就可以无限劫持了。
搜索引擎劫持
事实上,HTTPS 站点还有个很大的来源 —— 搜索引擎。遗憾的是,国产搜索引擎几乎都不提供 HTTPS 服务。因此在不安全的网络里,搜索结果是不具备任何权威的。
防范措施:重要的网站必定使用 HTTPS 协议,登陆时需格外留意。
国外的大型网站几乎都提供 HTTPS 服务,甚至是默认的标准。相比国内只有少数重要的服务才使用,绝大多数的信息都是在明文传输。这是为了方便什么来着,你猜。
流量劫持能否控制我电脑?
如果不考虑一些浏览器安全漏洞,理论上说网页与系统是完全隔离的,因此无需担心系统受到影响。
钓鱼插件
有时为了能让网页获得更多的在线能力,安装插件必不可少,例如支付控件、在线播放器等等。在方便使用的同时,也埋下了安全隐患。
如果是一些小网站强迫用户安装插件的,大家几乎都是置之不理。但若一些正规的大网站,提示用户缺少某些插件,并且配上一些专业的提示,相信大多都会选择安装。而这一切,通过被注入的攻击脚本完全能办到。
不过,正规的插件都是有完整的数字签名的,而伪造的很难躲过浏览器的验证,会出现各种安全提示。因此,攻击者往往使用直接下载的方式,提示用户保存并打开安装包。
页面提权
现在越来越多的应用程序,选择使用内嵌网页来简化界面的开发,在移动设备上更是普遍。
通常为了能让页面和客户端交互,赋予一些本地程序的接口供调用,因此具有了较高的权限。不过,正常情况下嵌入的都是受白名单限制的可信页面,因此不存在安全隐患。
然而在被劫持的网络里,一切明文传输的数据都不再具备可信度。同样的脚本注入,就能获得额外的权限了。
一些带有缺陷的系统,攻击脚本甚至能获得出乎意料的能力。通过之前提到的网页缓存投毒,这颗埋下的地雷随时都有可能触发。
下载程序
即使上网从不安装插件,但是下载程序还是经常需要的。由于大多数的下载网站,使用的都是 HTTP 流量,因此劫持者能轻易的修改可执行文件,将其感染上病毒或木马,甚至完全替换成另一个程序。
用户总认为从官网上下载的肯定没问题,于是就毫无顾虑的打开了。这时,入侵的不再是浏览器环境,而是能控制整个系统了。
防范措施:如果是从浏览器里下载的程序,留意是否具有数字签名,正规的厂商几乎都会提供。如果想试用一些来路不明的小程序,保存到虚拟机里使用就放心多了。
未来 SPDY 技术普及的时候,就再不用担心网页劫持这些事。它将 HTTP 协议封装在加密的流量里传输,想劫持一个普通网页都很困难了。
结尾
暂时就说到这。事实上类似 XSS 的攻击方式还有很多,这里只谈了一些能和流量劫持配合使用的。利用上一篇讲述的各种劫持途径,配合本文提到的入侵方式,可以劫持不少用户了。下一篇,将演示如何利用这些原理,发起实战攻击。