防范措施:
所以无论是 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 流量因此遭到劫持。
在经历越来越多的入侵事件之后,人们逐渐意识到,不能再轻易的让用户接受不信任的证书了。如今,主流浏览器对此都会给予严重的警告提示,避免用户进入伪安全站点。
如果重要的账户网站遇到这种情况,无论如何都不该继续,否则大门钥匙或许就落入黑客之手。
因此,这种偷换证书的劫持,在安全意识越来越高的今天,很难再发挥实效了。我们需要一个更隐蔽的方式来躲开加密数据。
(责任编辑:安博涛)