腾讯徐少培:浏览器地址栏之困

潘柱廷:下面有请腾讯玄武实验室技术专家徐少培,他演讲的题目是《浏览器地址栏之困》,有请!

徐少培:大家下午好,我今天下午演讲的主题《浏览器地址栏之困》。

徐少培

上周Chrome发布了最新的版本,在安全漏洞当中,其中有16个漏洞是由外部人员提交的。在这16个漏洞当中,中高危漏洞占了12个,获得了谷歌的漏洞奖励。在这12个漏洞当中,有3个漏洞是地址栏上的漏洞,也就是说,Chrome浏览器作为目前业界公认的最安全的浏览器,其中有四分之一的比例是地址栏上的安全漏洞,这个比例还是比较高的。也间接的说明,现代浏览器地址栏逐渐成为了越来越多的攻击者研究人员按照的对象。

地址栏上的安全问题都有哪些?这些漏洞有什么危害?以及我们如何在地址栏上来展开漏洞挖掘?本议题也正是基于此来和大家探讨一下地址栏上的安全问题都有哪些,这其中包括对地址栏安全指示符上的一些反思。在这个过程当中,通过我发现的三个Chrome地址栏上的漏洞,来总结一下地址栏上漏洞挖掘的思路和技巧,其中我提出了一个理论,就是如何深刻的理解地址栏之困,才能更好的挖掘地址栏上的漏洞。

首先做一下自我介绍,我来自于腾讯玄武实验室的研究员徐少培,主要是从事Web安全研究以及浏览器安全研究,主要是它们的前端研究。曾经和余弦合写了一本书,《Web前端黑客技术揭秘》,在我的微博上面会有一些对于Web前端的总结和分享。

提到地址栏大家肯定不陌生,因为每天都在用,大家有没有思考过这个问题,地址栏的重要性到底有多重要?谷歌在漏洞奖励的网站上公开的说了这句话,就说我们认为,在现代浏览器当中,地址栏是唯一可靠的指示器。这句话应该如何理解?就是通俗一点的讲,如果地址栏上出现了问题,后续我们所见到的Web页面,可信任的这些体系将全部崩塌,这么理解就可以了。对于浏览器厂商来说,他们的主要任务是消除软件当中的缓冲区溢出漏洞。对于浏览器厂商来说,还有一个更为挑战的事情之一,就是如何帮助人们在上网的时候做出安全的决策,就是让用户自己做出安全决策,这也是他们的挑战之一。这个安全指示符就是他们在这上面所做的工作之一。

大家可以看到这一页PPT上的安全指示符琳琅满目,可能大家也比较熟悉,有很多见到过。对于这个指示符上一度出现了混乱,就是大家弄不清楚这个指示符到底是指示一个什么状态。对于安全指示符,它的目的就在于如何表示当前网站的安全状态,比如说一个盾牌,一个小锁或者说一个其他的图标。我们来看一个HTTP的网站状态,看一下这几大浏览器厂商是怎么设计它们的标识符的。Chrome就是一个绿色的小图标,这是一个灰色的大图标,Firefox也是绿色的,但是它的绿色的颜色跟Chrome还不太一样,Safari是一个小图标,还有一个盾牌,国内的浏览器可能是一个运行的地球。这么多对同一个技术状态的描述,用了不同的指示符,所以大家有时候看起来比较困惑。谷歌2015年的时候做了一个调查,大家对地址栏上的指示符到底是不是真正的了解,我们是不是需要提取或者精简这个地址符来帮助人们做出正确的抉择。

在谷歌调查的1329人当中,这是匿名调查,其中提出了两个问题。就是说你对HTTPS网址,对左边的这个符号是否了解,如果是HTTP的话,你对HTTP左边的白色符号是否了解,在场的嘉宾是不是心里有一个清楚的答案?最后的结果其实很尴尬,在访问的1329人当中,大部分人对于HTTPS这个指示符还知道,看到有一个锁,就知道可能是加密或者是安全的问题。对于HTTP这个标识符,包括有一些专家在内可能都不太明白是什么意思。

我再提一个问题,大家觉得这个地址栏上的安全指示符只是一个符号还是一个按钮?有没有人点开过,看一下它里面是不是有东西?可能在座的点开的不多。如果你点开过,里面有很多安全的选项,权限的开启你是否都明白呢?当你点开这个指示符的时候,其实里面有更多的对当前页面权限的设置,包括你自己的设置,以及这个网站是否安全等等一些选项。浏览器厂商做了这么多工作,其实未必普通用户都了解。而且还有一点就是,在设计HTTPS指示符的时候,是不是只用绿色的就可以了?针对于色盲来说,可能他们考虑的是形状,而不是颜色,对于他们有一定的困惑,这可能都是以后需要去更多的优化的。

说完了地址栏上最前面的指示符,现在说一下地址栏当中真正的主角URL。URL的定义是从1994年的时候发布了第一个标准,事隔4年,在1998年的时候发布了扩充版叫RRI。当时发布完这两个标准以后,大家都觉得出现了问题,因为当时这两个标准当中是在网址当中只允许这个码,也就是说,如果世界上有各国语言的话,比如阿拉伯语言,我想在URL中进行体现是不行的,这个标准不支持。到后来又停了,1998年到2005年停了7年的时间,于是各个组织终于妥协,决定再发布一个新的标准,可以让它支持Unix的字符集,2015年的时候发布了IRI,就是国际统一指示符。从2005年到现在,又过了12年的时间,最终大家妥协,提起网址不要有什么歧义,不要觉得网址又是URL又是URI又是IRI,到底是什么呢?于是大家公认,现在由Whatwg维护的这个标准,一提到网址就是URL,而且URL目前维护的这一套标准,也已经覆盖了当时的IRI和URI这一套东西。所以它就明确指出,把之前的一些URL当中的一些历史包袱全都统统的逐步的遗弃,使网址标准这个词能够统一。所以大家以后再提到网址,现在浏览器当中就是URL,如果别人跟你说URI或者是IRI是很老的了,目前URL这个标准已经完全能够覆盖。而且这个标准还提出,URL的解析,应该像HTML的解析一样坚固,不要有太多的歧义。

刚才专门抽了一页来说URL,是为了让大家更清晰的了解,而不至于我们在之后的漏洞挖掘过程当中对URL有一些什么歧义。地址栏漏洞的关键因素就是URL,如果你熟悉了URL当中所有的参数都是什么功能,那么你再进行漏洞挖掘的时候就会比较更轻松一些。我列举的这个当中的例子大家看,基本上已经拆分得很细了。从协议上来说,除了本地协议,还有网络协议,还有一些已经公开注册的协议,比如说HTTP、HTPPS,还有一些伪协议,这些协议在浏览器处理的时候都有可能出现问题。还有一个是主机,比如多级域名的时候,比如三级域名、四级域名的时候,浏览器地址可视为很小的时候,可以把主机的覆盖掉,而显示前面伪装的多级域名主机,这个有问题。对于端口,目前默认的端口是空,或者是无符号16位的一个整形。大家有没有想过?如果超过65535,比如说是1万的浏览器端口,如果是ABCD端口会怎么处理呢?之后都会说到。再往下的参数是Passname,就是后面的目录,有可能会伪造成主机。再往下看井号后边,有可能浏览器格式在字符串的时候出现问题,User Name有可能会伪造成主机。

我们说了这么多基础的概念,什么是地址栏上的漏洞,地址栏的漏洞指的是什么?这里所说的地址栏上的伪装漏洞就是URL Spoof,本质是乌枣了Web最基本的安全边界。大家知道,大家知道,Web当中最扎实,最有根基的就是同源策略,如果这个源被伪造,后续所有的安全体系将会全部崩塌。这个起源指的是什么呢?起源指的是协议加上主机,加上端口。大家通过浏览器厂商得到的反馈来说,普通用户,包括开发者来说,往往不太了解这个源的概念到底是什么,而更倾向于主机是什么。所以大家在访问HTTP协议的时候,比如访问163,大家可以看到,在地址栏当中,URL其实并没有HTTP这个字符,是空的。默认端口也是被忽略掉的,如果是80的话,也不会在URL当中看到80端口,比如说是81就会显示出来。这个其实是浏览器厂商有意而为之的,简化了地址栏当中UI的显示,让更多的人可以通过一看是主机就可以了,不用去考虑底层的东西,但是这些简化也并没有去破坏掉底层的同源策略任何的概念。既然说到只要伪造主机就可以了,那么主机包括什么?包括域名和IP,IP包括IPv4和IPv6。所以你只要伪造了主机这一个字符串,你就可以说这是一个URL Spoof漏洞。我给了一个比较完美的URL Spoof漏洞,这是攻击者伪装的页面,也是改写的和谷歌一模一样的。用户的视觉感官上来看已经到达了谷歌,在其中输入信息的时候,你的信息就会完全被攻击者获取到了,这是最完美,最经典的一个URL的案例,就是这样,用于钓鱼用是非常好用的。

刚才我说了,URL当中的任何一个部分都有可能成为触发URL首先的关键要素。比如我列举的这个URL,大家可以看到它是一个四级域名构成的,后面的Passname的路径也是伪造成了一个类域名的字符串。在正确的地址栏中显示,不管URL有多长,不管地址栏可视区有多长,都要把这个正确的源显示出来,这个URL当中正确的源是什么?大家应该比较清楚,就是evil.com。所以在前5个显示当中,不管怎么变化都把正确的源显示出来了。对于有逻辑性问题的URL地址栏显示,比如在最下面两个也经常常见,Chrome就犯过这样的问题。最下面的两个当中的第一个,只显示了URL最左边的字符串,因为这个URL的地址栏长度有限,所以显示不全,看到的就是一个Bank.com,伪造了一个银行的网址。第二个只显示了URL右边的字符串,同样是隐藏掉了真正的源,所以看到的又是一个假的URL。这个就相当于没有太多的技术性操作,只是说这个地址栏的自身逻辑性问题,显示问题,造成了这个地址栏欺骗。而前面的是由多级域名造成的,后面是由Passname造成的,任何一个匀速都有可能造成这个欺骗。

接下来用我去年连续发现了三个Chrome地址栏上的漏洞来分析和总结一下地址栏上的漏洞应该如何挖掘,并且提出地址栏之困,就是挖掘URL Spoof漏洞的核心要义。2016年的时候,我6月份、8月份和10月份,连续在Chrome的三个版本当中发现了三个不同的安全问题。这三个问题的触发方式都不太相同,比较有代表性,在这里给大家说一下。

第一个漏洞是在iOS平台下触发的。当时了获得了URL漏洞的最高奖励,谷歌的3千美元。漏洞呈现的最后攻击效果就是这样的,当用户点击了一个链接,到达了Gmail,但是这个Gmail的URL是由攻击者伪装的,页面也是由攻击者伪装的。当你登录Gmail的时候,输入用户名和密码的时候,你的信息就被攻击者获取到了。

我们来看一下这个漏洞的原理是如何实现的。我在这里给出来一个最简的POC,来说明一下这个漏洞的流程。就是当用户点击这个按钮的时候,打开了一个页面,写下了一堆代码,把这个代码我专门抽出来,用灰色来标识,就是关键代码。这个代码是在当前页面用A标签自身又打开了一个窗口,导航到了一个地址,大家看到黄色标识的URL就是导航的地址。但是可以看到,这是一个畸形的URL,最后有两个冒号,就是浏览器基本上默认是无法去解析的,于是漏洞就触发了。这个黄色的畸形的URL到底后续使浏览器发生了什么呢?首先到了刚才畸形URL那个位置的时候,当用A标签去打开一个新的页面,首先浏览器的导航机制是这样的,它先判断一下是不是允许跳转到一个页面,当时Chrome碰到这个畸形的URL的时候,它允许去加载,这就是错误的开始。你加载了一个无效的地址,而且在这个过程当中没有任何的判断,也没有任何的处理。当你同意加载,第二步就开始加载了。当加载了这个畸形的URL的时候,因为加载的是无效的地址,根本没有办法去访问。于是,地址栏就处于了一个挂载的状态。加载完了以后就开始反馈数据,就是浏览器加载的流程开始返回。因为你加载的是一个无效的,所以什么也没法返回,只能返回一个空的页面,也就是说返回了一个空域。但是此时Chrome挂起状态还停留在那里,而且早最后还要把挂起的这个地址作为最后的提交地址来显现在这个地址栏当中。于是第四不就是页面加载完成,就是结束,然后就停留在了刚才我们看到的这个页面当中。而且会把那两个冒号完全隐藏掉,就是出来了这个效果,就是刚才我说的那个漏洞的流程。

第二个问题是在这个漏洞发现之后的后两个月,我又连续寻找看还有没有新的漏洞。那个应该是在53版本,这个应该是在修复以后54版本。当时我在翻协议的时候就发现,其实还有不同的协议浏览器处理还是不同的,还是我刚才说的那句话,你一定要熟悉URL当中的任何一个元素,这个就是因为协议的不同而导致的一个欺骗。这个漏洞当时谷歌定义是给了500美金。这个协议是发生在Blog协议上,我简单说一下,Blog协议其实是一个二进制文件的容器,Blog URL允许外部应用程序安全的访问内存中二进制的文件,也就是说,对于内存中二进制文件的一个Blog引用。按理说安全同源策略来说,你不可能直接打开一个你不能控制域的Blog的URL,通过这个页面,从视觉感官上是成功打开了谷歌域的Blog的URL,其实是伪造的。如何做到的?当你点击了这个按钮之后,其实首先打开了一个攻击者可控制域的Blog的URL,就是下面这个黄色的关键核心的。过了500毫秒之后,在这个页面上写入伪造内容。大家可以看到黄色的关键代码,@后面的域才是攻击者的域,就是我可控制的,而前面的那些都是伪造的。首先伪造了一个谷歌的字符串,后面进了大量的空白字符。浏览器遇到这样的字符串,这样的URL。10前来说这个是正常的URL,但是现在已经不允许了,我一会儿会说一下为什么。Chrome会怎么处理呢?Chrome其实犯了一个逻辑上非常严重的错误,他一直在对HTTP、HTTP做了很多限制,可能边缘化的协议没有太注意。其实它渲染了用户名和密码的部分,就是@符号前面的部分,按理说应该不会去渲染。就是你可以去解析,但是你在UI上显示的时候不能显示出来。因为一个URL的用户名和密码一旦被渲染,极有可能被用户认为是这个URL的主机。比如下面我列举的这个链接,如果直接全被渲染的话,@前面的字符串就有可能被认为是这个主机,也就是伪造了这个域名。

当我在主机前面加入了伪造字符串之后,又加入了大量的空白符号,在现在的浏览器当中已经不允许这么做了,大量的空白被解析的话,就会被真正的主机的域名覆盖掉,就冲到后面去了。Chrome对于这个Blog协议,按理说应该像对待HTTP协议这样解析、安全,应该做到位,但是出现这两个问题,这两个问题应该是七八年前浏览器经常出现的问题,所以说协议的不同,可能会造成你完全想像的不同,就是不要认为HTTP、HTTPS已经做得很完善了,可能在协议这一块已经没法再找到漏洞了,但是还有很多不同的协议,包括伪协议等等,都有可能出现这种问题。

第三个漏洞是10月份发布的55版本,我再去看到底还有没有地址栏问题,通过了不同的方法。最后通过了一个很神奇的触发的方式,又发现了一个问题。这个触发方式就是说,其实大家在导航到一个新的网站的时候可能都用左键去点击。有没有想到过,比如说我麻烦一点,点击右键,再点击从新窗口打开这种方式,可能现实当中很少人这么做,但是确实能打开一个新的网站,这个漏洞就是通过这种方式去触发了这个URL欺骗的漏洞。大家可以看一下,最后欺骗的效果就是说伪造了谷歌的域,页面内容同样可以被改写,这个漏洞因为触发起来可能需要的一个小交互,所以当时只给了500美金的奖励。

我说一下现在Chrome通常的奖励标准,如果你在PC端发现了比较完美的,可能给到2千刀。如果是移动端比较完美的,就像我刚才在iOS上面,一看就是谷歌,后面也没有加任何字符,而且协议也是,能给到3千刀。如果交互和协议只是伪造了一半等等,这种可能会给到500刀。而且近期来说,谷歌以前对于低级的漏洞还给500刀,现在可能只给中高级漏洞。

这个漏洞其实触发起来核心代码非常简单,就是一句话,当然是比较难想到的。就是右键点击,出来了一个UI,当中会有一个你是不是从新窗口打开,我尝试了从新窗口打开。当时还是两个冒号,我想通过了两个版本的更新,是不是这个问题已经解决了?我打开之后,确实是导航到了谷歌,也是真正的域。但是它会显示出来一个冒号,我当时想,肯定是URL解析又出现了什么问题。于是我在当前通过第一个点了一下这个链接,发现它是你点了以后,能导航到别的网站。但是当前的URL并没有更新,这个很奇怪。我当时想,这又是一个URL欺骗漏洞。重定向的时候,URL没有更新,只是更新了内容。如果能够在谷歌上找到一个重定向,自动重定向,就完全可以伪造谷歌了。在谷歌上找到一个重定向,后边如果加一个重定向的链接如果相符的话谷歌是允许的。后面第二个Payload,我在自己的网站上写了一句话,导航到我的网站,大家可以看到,我抓包以后可以看到,其实在左边抓的,两个链接,其实都已经访问了,但是最终Chrome浏览器是停留在谷歌的网址上,但是页面内容是我的页面内容,可控制的,就造成了一个URL欺骗。这个Payload发生了什么?我们通过URL加载的过程来说一下,当你通过右键在新窗口打开,Chrome又允许加载一个无效的地址。当时在53版本的时候其实Chrome已经补了,当时不允许加载无效的网址,而且专门把这两个冒号标识出来了。但是没有补的时候,说通过不同的网站,不同的方式打开,通过右键去打开,可能导航又是另一套程序,这一块就没有考虑,还是可以加载google.com:的这样一个无效网址。加载以后,刚才我说的那一套流程又返回页面,把google.com:作为一个提交地址。其实到这里应该结束了,如果你在当前重定向到另外一个网上,不会更新当前的URL,URL还会停留在谷歌,其实你的内容已经重定向到了另一个网站的内容,于是又产生了一个URL的欺骗。

通过我从去年6月份到10月份连续发现的谷歌上面三个不同类型的URL欺骗的漏洞,大家想一想都是在什么情况下发生的。也就是说,用户在一个网站页面,你不管是点击、拖放还是右键,去导航到另一个网站的时候。在这个过程当中,攻击者伪造了你的目的地的URL,其实相当于你就没有到达目的网站,你是困在了你在哪儿和你要去哪儿的这个中间。其实理解这句话很困难,当时我就在想,什么样的情况能够触发这个URL?其实我觉得今天我所总结的这句话,下面我要说的就是我总结的结论,浏览器地址栏其实是一个挺矛盾的个体,它提供两个相互竞争的角色,这两个角色就是你在哪儿和你要去哪儿,但是只能显示出其中的一个。而地址栏恰恰就困在这两个角色的转换之中,其实你没有真正的转换到你要去哪儿,就已经被攻击者伪造了你要去哪儿的那个网站了,就停留在那儿了。所以说从视觉感官上来说,你也被困在里面了,这就是今天我罗嗦了这么多,最后这句话我觉得就是完全的挖掘URL漏洞最核心的要义。不知道大家能不能体会,可能你挖掘的时候才能体会到我说的这句话。就是从去年6月到10月,五六个月的时间所总结出来的。说了这么多,最后就是这一页PPT是最核心的要义。

讲到这里基本上今天的分享就结束了,对于地址栏上的安全可能还有更多的挑战,我在这里再提几点。对于地址栏上的指示符还需要进一步的优化,能不能优化的更简单一些,大家都能看懂,尽快的帮助人们上网的时候做出安全的决策。地址栏在处理常网址、多网址、畸形网址的时候,不是程序的问题,是自身的地址栏显示的逻辑问题。比如说只显示最左边或者是只显示最右边,少一些逻辑上明显的漏洞。现在浏览器屏幕会越来越小,大家用到的手机,地址栏上的UI可以说是寸像素必争了。又要提供安全性,又要显示你是HTTPS是加密的,还要显示出来正确的源是什么等等,估计空间也不够。所以在如何处理安全性和用户体验上,我觉得可能会是一个非常重要的挑战。最关键的就是大家能记住我这一页,如果挖漏洞的话,记住如何深刻的理解地址栏之困,在地址栏上能够如何有效的开展漏洞挖掘工作,也是我们进一步思考的问题。

今天就分享到这里,谢谢大家!

潘柱廷:谢谢徐少培的精彩演绎,尤其是最后一页提升了整个境界。尤其是关于地址栏最后的这种思索,为什么地址栏不放两行呢?当然现在屏幕越来越小。

徐少培:这个问题当时Chrome还在2013年的时候要去掉地址栏,就是完全全屏化,结果开启了几个月就完全把这个思想屏蔽掉了。也就是说,因为地址栏就是刚才我开篇说的,它是现在浏览器当中唯一可靠的指示器。如果没有这个指示器的话,完全就乱套了。当然你说两行那个是又一个问题,屏幕越来越小,本来就没有空间,你再有两行,可能空间不够,是这个考虑。

潘柱廷:比如当你真正想输入地址栏的时候,就意味着你要去那个地方的时候,这个时候弹出来两行,我觉得这个困很哲学。

徐少培:我一直跟Chrome很时间,包括它们的UI,这其实是我研究UI当中的一部分,就是地址栏,还有对话框是怎么设计的,还有UX就是用户体验怎么设计,这个里面很细。刚才我说寸像素必争,真的是这样,他们会考虑0.5像素往左还是往右一点的标识符,这个讨论就好几个月。

提问:除了跟Google的浏览器,还跟哪些别的浏览器吗?世界上很主流的。

徐少培:还有Safari浏览器已经挖掘了有十几个UI上的地址栏欺骗漏洞,最近主要我就是研究Safari和Chrome的浏览器。

上一篇:腾讯马劲松:WannaCry病毒事件的反思

下一篇:安恒郑国祥:strust2漏洞挖掘经验分享