前言
HSTS 的出现,对 HTTPS 劫持带来莫大的挑战。
不过,HSTS 也不是万能的,它只能解决 SSLStrip 这类劫持方式。但仔细想想,SSLStrip 这种算劫持吗?
劫持 vs 钓鱼
从本质上讲,SSLStrip 这类工具的技术含量是很低的。它既没破解什么算法,也没找到协议漏洞,只是修改和代理了明文的封包而已。
如果说劫持,要保持源站点不变才算的话,那 SSLStrip 并没做到。根据同源的定义,<协议, 主机名, 端口>
三者必须相同。显然它修改了协议,因此并非在源站点上劫持,而是进入了另个不同的站点。
既然站点都不同,那就属于钓鱼网站了。
但这种钓鱼之所以会如此隐蔽,和大家的常理有关:对大部分用户来说,只要主机名正确那就对了,至于协议和端口,很少有人去关心。
而 SSLStrip 正好利用了人们的认知弱点,确实没有修改网站主机名,从而欺骗了大部分用户。
因此更确切的说,这就是一种高级钓鱼。
进一步钓鱼
由于 HSTS 这种反钓鱼的机制出现,即使蒙的了用户,但也骗不过浏览器。
HSTS 正是以主机名为单位的。在新的版本里,甚至还支持所有子域名(includeSubDomains)。
如果还抱有侥幸心理,期望能过滤首次的 HSTS 头,那么 Preloading HSTS 能让浏览器天生就记住某些网站。彻底打消 SSLStrip 的念头。。。
不过,刚刚也说了,SSLStrip 本质就是网站钓鱼。既然都钓鱼了,何必这样鬼鬼祟祟的反倒被发现,为何不正大光明的钓?
反正钓鱼考的就是用户眼力,不如再进一步,干脆把主机名也改了吧!眼力不好的人,可能还是看不出破绽。
例如,将原本 https://www.alipay.com
的链接,跳转到 http://www.alipay.cn
这个钓鱼网站,仍会有不少用户觉察不到。
而 www.alipay.cn
这个虚假的主机名,显然不会在 HSTS 白名单中,因此又可以无限劫持了!
在流量劫持的环境里,任何明文数据都是可控的。即使访问 www.alipay.cn
这种不存在的域名,中间人也可模拟 DNS 应答,从而可伪造出各种看起来相似的钓鱼站点。
在之前那篇 《SSLStrip 的未来 —— HTTPS 前端劫持》 中,我们是在 URL 的 Query 中进行伪装的:
虽然修改了 URL,但主机名没变,因此仍躲不过 HSTS。
所以,我们需要将 symbol 标记转移到域名里:
将页面中出现的 HTTPS 域名稍作修改,就是完全不同的一个站点了,因此即可彻底摆脱 HSTS 的白名单。
例如把域名都替换成 .cn 的,原本 www.alipay.com
就变成 www.alipay.cn
了,这样即使用户浏览器里存在 HSTS 记忆,那也是之前的,这个临时伪造出来的钓鱼站点,自然不会有的。
尽管站点完全不同,但表面上看起来仍是相似,因此用户仍然不易察觉。
同时,中间人能够识别出域名中的这个被修改过的特征,在转发时还原回先前的域名,进行正常代理。
保留绿色证书
对于大部分用户来说,地址栏里醒目的 HTTPS 绿色证书,是一只强心剂。而 SSLStrip 剥离了协议,显然是不可能出现了。
但如今通过修改主机名,能否要回这个图标?
如果想有,显然得申请一个合法的证书。但要将所有的 .cn 域名都配上数字证书,肯定是不现实的。
不过既然是钓鱼网站,主机名也可以随意改,何必困死在*域名上?
我们可以申请一个泛域名证书,例如 *.xx.com。这样,将目标站点都套在该二级域名下,即可以 HTTPS 协议进行钓鱼了。
(这里以自签署的证书演示)
虽然域名相比之前差别较大,但有醒目的绿色证书,反而更容易被蒙蔽了。
HSTS 的意义
由于钓鱼的方式可以千变万化,因此 HSTS 也很难从根本上进行防御。
当然,这并不意味 HSTS 没有实际作用。事实上 HSTS 还是能够避免很大部分的风险。其中最典型的,就是用户在地址栏里敲入网址的情况。
在过去,未提供的协议的网址,都是以默认的 HTTP 方式请求,因此在这个入口就有极大的风险。而 HSTS 的出现,很大程度的解决了这个隐患。
如今,像百度这样的大型导流网站,都在逐步支持 HTTPS 升级,从而在入口源头上堵住这个安全隐患。
防御方案
尽管是钓鱼,但也不是完全没有防御方案。
从攻击者的角度来看,如果要为各种站点制作一个钓鱼网站,成本是极大的。而且更新起来也不容易,数据也难以保持实时。
因此,通常是直接代理线上的站点内容。既然这样,不妨在网页中悄悄加入些监控脚本,统计当前页面究竟在哪些域名里出现过,就能快速找出一些钓鱼网站了。
当然,攻击者也可以过滤掉这段监控脚本,这就是后期对抗的事了。