徐少培,来自于腾讯玄武实验室的研究员,主要是从事Web安全研究以及浏览器安全研究(前端)。曾经和余弦合写了《Web前端黑客技术揭秘》。
本文通过徐少培三个Chrome地址栏漏洞,来总结一下地址栏上漏洞挖掘的思路和技巧,徐少培并提出如何深刻的理解地址栏之困,才能更好的挖掘地址栏上的漏洞的理论。
地址栏到底有多重要?
在现代浏览器当中,地址栏是唯一可靠的指示器。就是通俗的说,如果地址栏上出现了问题,后续我们所见到的Web页面,可信任的这些体系将全部崩塌。对于浏览器厂商,他们的主要任务是消除软件当中的缓冲区溢出漏洞。其次,如何帮助人们在上网的时候做出安全的决策。这个安全指示符(地址栏)就是他们在这上面所做的工作之一。
安全指示符
安全指示符,它的目的就在于如何表示当前网站的安全状态,比如说一个盾牌,一个小锁或者说一个其他的图标。常见的浏览器厂商是怎么设计它们的标识符的?Chrome就是一个绿色的小图标,这是一个灰色的大图标,Firefox也是绿色的,但是它的绿色的颜色跟Chrome还不太一样,Safari是一个小图标,还有一个盾牌,国内的浏览器可能是一个运行的地球。
这么多对同一个技术状态的描述,用了不同的指示符。谷歌2015年的时候做了一个调查,大家对地址栏上的指示符到底是不是真正的了解,在谷歌匿名调查的1329人当中,其中提出了两个问题。一,你对HTTPS网址,对左边的这个符号是否了解,如果是HTTP的话,你对HTTP左边的白色符号是否了解。最后的结果其实很尴尬,在访问的1329人当中,大部分人对于HTTPS这个指示符还知道。对于HTTP这个标识符,大部分人不知道答案。
URL
1994年的时候发布了第一个标准URL,在1998年的时候发布了扩充版RRI。2005年的时候发布了IRI,就是国际统一指示符。
网址到底是什么呢?是URL?是URI?是IRI?公认网址就是URL,而且URL目前维护的这一套标准,而且这个标准还提出,URL的解析,应该像HTML的解析一样坚固,不要有太多的歧义。
漏洞挖掘过程当中对URL有什么意义?
地址栏漏洞的关键因素就是URL。又分为协议、主机、端口、参数、目录几部分
协议分为本地协议,网络协议,注册的协议,比如说HTTP、HTPPS,这些协议容易出现安全问题。
主机,当浏览器地址很小,可以把主机的覆盖掉而显示前面伪装的多级域名主机。
对于端口,目前默认的端口是空,或者是无符号16位的一个整形。端口过多可以出现问题。
地址栏漏洞
什么是地址栏上的漏洞,这里所说的地址栏上的伪装漏洞就是URL Spoof,本质是Web最基本的安全边界。
Web当中最扎实,最有根基的就是同源策略,如果这个源被伪造,后续所有的安全体系将会全部崩塌。这个起源指的是什么呢?起源指的是协议加上主机,加上端口。
对于浏览器厂商,普通用户报货开发者都不关注源是什么,而倾向于主机是什么,所以在地址栏当中,只要伪造主机就可以了。你只要伪造了主机这一个字符串,你就可以说这是一个URL Spoof漏洞。
地址栏漏洞如何挖掘
此处用三个Chrome地址栏漏洞来分析地址栏上的漏洞应该如何挖掘
第一个漏洞。当用户点击了一个跳转到Gmail,由于Gmail的页面是攻击者伪装的。当你登录Gmail,输入用户名和密码,你的信息就被攻击者获取。
这个漏洞是如何实现的。
当用户点击这个按钮的时候,打开了一个页面,写下了一堆关键代码。这个代码是在当前页面用A标签自身又打开了一个窗口,导航到了一个地址这是一个畸形的URL,最后有两个冒号,就是浏览器基本上默认是无法去解析的,于是漏洞就触发了。这个畸形的URL会使浏览器发生了什么呢?
当Chrome浏览器运行到畸形的URL时,它允许去加载,这就是错误的开始。当加载了这个畸形的URL的时候,因为加载的是无效的地址,根本没有办法去访问。地址栏处于挂载的状态。加载反馈数据,就是浏览器加载的流程开始返回。因为你加载的是一个无效地址,只能返回一个空的页面,也就是说返回了一个空域。此时Chrome还处于挂起状态,于是会冒号完全隐藏掉并显示最后的地址。
第二个漏洞。这个协议是发生在Blog协议上,我简单说一下,Blog协议其实是一个二进制文件的容器,Blog URL允许外部应用程序安全的访问内存中二进制的文件,也就是说,对于内存中二进制文件的一个Blog引用。按理说安全同源策略来说,你不可能直接打开一个你不能控制域的Blog的URL,通过这个页面,从视觉感官上是成功打开了谷歌域的Blog的URL,其实是伪造的。
如何做到的?当你点击了这个按钮之后,其实首先打开了一个攻击者可控制域的Blog的URL,就是下面这个黄色的关键核心的。过了500毫秒之后,在这个页面上写入伪造内容。大家可以看到黄色的关键代码,@后面的域才是攻击者的域,就是我可控制的,而前面的那些都是伪造的。首先伪造了一个谷歌的字符串,后面进了大量的空白字符。浏览器遇到这样的字符串,这样的URL。10前来说这个是正常的URL,但是现在已经不允许了,我一会儿会说一下为什么。Chrome会怎么处理呢?Chrome其实犯了一个逻辑上非常严重的错误,他一直在对HTTP、HTTP做了很多限制,可能边缘化的协议没有太注意。其实它渲染了用户名和密码的部分,就是@符号前面的部分,按理说应该不会去渲染。就是你可以去解析,但是你在UI上显示的时候不能显示出来。因为一个URL的用户名和密码一旦被渲染,极有可能被用户认为是这个URL的主机。比如下面我列举的这个链接,如果直接全被渲染的话,@前面的字符串就有可能被认为是这个主机,也就是伪造了这个域名。
第三个漏洞。这个漏洞其实触发起来核心代码就是右键点击,出来了一个UI,当中会有一个你是不是从新窗口打开,。
抓包以后可以看到,其实在左边抓的,两个链接,其实都已经访问了,但是最终Chrome浏览器是停留在谷歌的网址上,但是页面内容是我的页面内容,可控制的,就造成了一个URL欺骗。这个Payload发生了什么?我们通过URL加载的过程来说一下,当你通过右键在新窗口打开,Chrome又允许加载一个无效的地址。当时在53版本的时候其实Chrome已经补了,当时不允许加载无效的网址,而且专门把这两个冒号标识出来了。但是没有补的时候,说通过不同的网站,不同的方式打开,通过右键去打开,可能导航又是另一套程序,这一块就没有考虑,还是可以加载google.com:的这样一个无效网址。加载以后,刚才我说的那一套流程又返回页面,把google.com:作为一个提交地址。其实到这里应该结束了,如果你在当前重定向到另外一个网上,不会更新当前的URL,URL还会停留在谷歌,其实你的内容已经重定向到了另一个网站的内容,于是又产生了一个URL的欺骗。
用户在一个网站页面,你不管是点击、拖放还是右键,去导航到另一个网站的时候。在这个过程当中,攻击者伪造了你的目的地的URL,其实相当于你就没有到达目的网站,你是困在了你在哪儿和你要去哪儿的这个中间。
浏览器地址栏其实是一个挺矛盾的个体,它提供两个相互竞争的角色,这两个角色就是你在哪儿和你要去哪儿,但是只能显示出其中的一个。而地址栏恰恰就困在这两个角色的转换之中,其实你没有真正的转换到你要去哪儿,就已经被攻击者伪造了你要去哪儿的那个网站了,就停留在那儿了。从视觉感官上来说,你也被困在里面了
对于地址栏上的指示符还需要进一步的优化,尽快的帮助人们上网的时候做出安全的决策。地址栏在处理常网址、多网址、畸形网址的时候,不是程序的问题,是自身的地址栏显示的逻辑问题。比如说只显示最左边或者是只显示最右边,少一些逻辑上明显的漏洞。现在浏览器屏幕会越来越小,大家用到的手机,地址栏上的UI可以说是寸像素必争了。又要提供安全性,又要显示你是HTTPS是加密的,还要显示出来正确的源是什么等等,估计空间也不够。所以在如何处理安全性和用户体验上,我觉得可能会是一个非常重要的挑战。最关键的就是大家能记住我这一页,如果挖漏洞的话,记住如何深刻的理解地址栏之困,在地址栏上能够如何有效的开展漏洞挖掘工作,也是我们进一步思考的问题。