Android WebView 攻防指南

admin 99 0



WebView是App中的一个核心组件,也是App内部与Web世界交互并呈现给用户的一个窗口,目前已广泛应用于很多 App中。

自诞生伊始,Android WebView就充斥着各种各样的重大漏洞,这既与系统WebView有关,也与WebView复杂的使用有关,导致其容易被开发者误用

毫不夸张的说,WebView已成为Android App中最重要的远程攻击面,也是最容易出现重大漏洞的薄弱环节

下面就让我们来回顾看雪2020第四届安全开发者峰会《Android WebView安全攻防指南2020的精彩内容。


演讲嘉宾

Android WebView 攻防指南-第1张图片-极光之门

何恩,OPPO子午互联网安全实验室安全专家,专注于Android 安全,擅长Android App和框架层的漏洞挖掘,获得过几十个Google Android VRP和GPSRP安全致谢,在原乌云知识库、先知安全论坛和OSRC公众号发表过多篇有影响力的Android安全文章。

 

曾任中国电科第三十研究所安全专家,安全领域从业16年,在CNCERT 2016和POC 2018安全峰会上发表过有关Android安全的技术演讲。


演讲内容

以下为速记全文:


大家好,我是何恩,我今天给大家带来的是一个有关安卓APP应用安全攻防的议题。这是我的一个自我介绍,我所擅长的领域主要还是在安卓的AOSP框架层和APP层面的漏洞挖掘。


我今天分享的内容包括以下五个方面,首先会从Android WebView诞生时期的漏洞讲起,介绍其安全攻击面,从而引出它的安全配置和使用,然后介绍目前经常出现的URL白名单校验问题,接下来是安全防御的实践,最后是总结。

一.WebView攻击面

首先介绍Android WebView漏洞的基本模型。WebView是安卓APP内部的一个浏览器,是APP与外部世界交流的窗口。由于它的功能非常复杂,商业化的需求导致它的功能繁多,配置也非常多,此外它还有众多的JS层面的回调函数,导致Android WebView容易出现一些比较严重的安全问题。Android WebView漏洞的根源就在于强制其访问了攻击者控制的网页。由于网页中含有攻击者可以控制的JS,因此可能钓鱼、窃取私有目录文件、甚至是RCE,带来比较大的危害。

Android WebView 攻防指南-第2张图片-极光之门

从Android WebView的攻击面来看有三类,常见的就是通过Android WebView本地的通信接口,第二个就是一个远程攻击面,用户通过点击一个APP自定义的伪协议从而拉起WebView访问攻击者可控的网页,除此之外还有一些特殊的攻击面。前面已经有嘉宾分享了针对浏览器内核的方面,而今天我分享的议题则是主要在于WebView的不当配置和使用。


回顾WebView的攻防发展历程,在其刚刚开始使用的时候,在安卓5.0以下,4.4版本左右的时候,大家比较关注的漏洞就是系统的JsInterface接口暴露。有研究者发现可以通过这个去反射执行任意代码,从而导致RCE,这在当时非常常见,也是安卓中非常著名的漏洞。


在WebView使用的中期,可能两年前左右,我们可以看到一些由于WebView跨域配置不当导致的私有文件窃取的漏洞,当时玄武实验室把漏洞的危害进行了放大,如果对APP的所有私有文件都进行了窃取,甚至可以把受害用户的身份信息克隆到另外一个设备中去。


而现在,我们可以看到形形色色的WebView漏洞,主要是由于URL校验不当,从而导致加载任意网页或者是调用一些特权接口


回顾历史漏洞,就是在Android 4.4之前,系统存在JavaScriptInterface接口,可以被反射调用执行任意代码。之前我挖掘过一个某地图APP的漏洞,它开放了一个端口号为6677的网络端口,我们可以通过访问这个网络端口去操纵APP内部的WebView,并访问攻击者可控的网页。虽然这个漏洞是比较古老的,但从安全编码的角度来看,还是建议开发者去除系统中不用的JsInterface接口。

二.WebView的配置与使用

接下来我们看一下WebView的配置与使用。其实有关WebView的配置与使用主要是集中在下面的设置当中,当setAllowFileAccess为true,下面的任一设置为true时,攻击者可以利用WebView的漏洞窃取APP任意目录下的私有文件。这也是一个非常常用的手法,这个操纵是需要WebView去下载恶意JS到手机中的公共存储区,然后通过AJAX去窃取私有文件。当时的应用克隆应该就是利用了下面这种手法。

Android WebView 攻防指南-第3张图片-极光之门

仍然只有setAllowFileAccess为true,其他两个设置均为false时,是否仍然可以窃取文件呢?答案是肯定的,第二种手法在WebView早期版本中有效,我把它称之为移花接木

它通过软链接的方式去窃取任意私有文件,这就意味着WebView不做任何设置(因为setAllowFileAccess为true是默认的),攻击者就可以WebView访问任意URL的漏洞来窃取用户APP的私有文件。


其攻击过程首先是操纵WebView去访问一个攻击APP自己公开出来的网页,然后这个网页执行的内容其实就是延时去读取自身。在延时读取自身的时间窗口内,这个文件悄悄被进行了替换,替换成了软链接,指向受害APP的一个私有文件,最终读取窃取其内容。

Android WebView 攻防指南-第4张图片-极光之门

其实还有一种方式。这个方式目前没有在公开场合被披露过,但在最近的一些WebView的版本上它仍然是有效的。在WebView存在访问任意URL的情况下,仍然只有setAllowFileAccess为true,如何放大攻击的危害呢?我把它称为含沙射影主要思路是去污染Cookies


Android WebView 攻防指南-第5张图片-极光之门

首先,让受害APP的WebView访问攻击者可控的网页,该网页设置一段特殊的Cookie,也就是在受害APP的Cookies文件中写入payload。


接下来攻击APP再次操纵WebView去访问自己开放的网页,这个网页其实是一个软链接,指向受害APP自己的Cookies文件。通过这样的一个过程,就能操纵受害APP去加载自己的Cookies文件。因为这个文件是自己的,所以一定能够加载出来,但是这个文件已经被我们污染了,里面的payload执行,也就会读取这个文件自身,从而放大了WebView任意加载漏洞的危害,并能窃取WebView所加载的所有的Cookies。

Android WebView 攻防指南-第6张图片-极光之门

图上是攻击的效果,大家可以看到,Cookies文件是被污染了一段js代码,接下来是软链接指向了受害APP的cookies文件。


下面,我再讲遇到的另一个有关loadDataWithBaseURL的使用案例。在这个案例中,该函数涉及到两个参数,一个是访问的域名,还有一个是访问的内容。我们经常能够看到,如果域名和内容同时可控,那么攻击者就可以构造一个任意域下的XSS漏洞。


Android WebView 攻防指南-第7张图片-极光之门

我要介绍的这个案例就是一个谷歌的流行APP,这个APP有很多的deeplink,可以用来操纵其WebView访问任意URL。由于WebView没有做任何设置,也就是默认设置,这就意味着它可以用前面我提到的手法去窃取它的Cookies文件。同时,它还有一个特殊的deeplink,可以让APP的WebView去通过谷歌Doc加载URL指定的链接,但这个URL是攻击者可控的,因此带来的危害非常严重,用户只要点击一次Deeplink,其access_token就会被发送到攻击者的服务器,从而让攻击者窃取用户的信息。


Android WebView 攻防指南-第8张图片-极光之门

该APP还有一些特殊的deeplink,可以加载攻击者指定的Fragment,但传入不存在的Fragment Class时,APP就会崩溃,原因是Fragment对应的类被实例化,但却不存在。


于是我就开始思考,如果传入APP中本身就存在的一些合理的Fragment Class时,会产生何种安全危害?这里我对它的上百个Fragment Class进行了尝试,最终将该漏洞转化为了WebView的loadDataWIthBaseURL漏洞利用,我这里可以控制前两个参数,从而实现了在漏洞APP自己域名下的XSS。

Android WebView 攻防指南-第9张图片-极光之门

对开发者而言,我的安全建议就是,需要把这些跨域的设置默认设置为false。如果开发者要加载确定的HTML,可以使用它自己的asset目录,同时也要防范目录穿越问题,对文件名进行过滤,尽量不使用loadDataWithBaseUrl。


Android WebView 攻防指南-第10张图片-极光之门

三.WebView URL校验

接下来我们进入URL校验部分。这里涉及到一个基本问题,就是很多APP的开发者会把自己的域名作为白名单域名,然后对这个域名进行检查,如果检查通过才会打开高敏感权限的JsInterface接口,或者说让WebView去加载。这就导致有很多误用URL进行检查的案例。


下面是一个简单的案例。比如说对File协议进行检查,有很多的方式可以去绕过。其中,正确的做法是从URL里取Scheme,忽略大小写再进行判断。


URL校验失校的案例非常多,常见原因有endWith没有闭合点号等。在没有闭合点号的情况下,攻击者可以在域名前加其他的字母进行绕过


还有使用startsWith、contains、indexOf、正则匹配等非严格字符串匹配方式,以及很多其他的绕过方式。

Android WebView 攻防指南-第11张图片-极光之门

除此之外,还有一种方式是通过WebView loadUrl与Uri.parse理解的不一致。对WebView的URL来说,它是正确理解,会把“\”识别为“/”,正常进行加载,但是在Uri.pase解析的时候没有对“\”进行处理,没有按照WhatWG规范把“\”识别为path的开头,就出现了不一致。这个漏洞对于安卓8.1及之前的版本都有效,所以攻击者用这种方式可以成功打击很多低于8.1版本的设备。

Android WebView 攻防指南-第12张图片-极光之门

下面是我针对这类漏洞遇到过的一些案例。对于某个视频编辑APP,发生过两次URL校验绕过。还有某音乐APP,也是使用了这个漏洞,只不过它是通过deeplink去控制URL参数,并使用“\”的技巧去绕过校验。另外,还有某聊天APP,它存在逻辑问题,会把自己的协议替换成HTTP,攻击者就可以在后面加上@符号进行绕过。


此外,还有一种是URL Scheme绕过,它检查了host但没有检查scheme,就可以通过“javascript:”绕过。需要注意的是,在WebView的低版本中,如果跟上白名单host和实际存在的文件的路径,WebView仍然可以正常解析。在WebView加载的时候,会忽略host,正常加载后面路径指向的文件,所以攻击者仍然可以用这种方式去绕过。

Android WebView 攻防指南-第13张图片-极光之门

下面来说说通过hearachical Uri绕过的方式,漏洞特征是直接从外部去取Uri,未经过Uri.parse,可以通过反射构造herachical Uri绕过

Android WebView 攻防指南-第14张图片-极光之门

如果白名单域名内的服务端出现跳转漏洞的时候,开发者没有对其进行检查,攻击者就仍然可以绕过。这种漏洞自身危害可能不大,但结合着WebView的特权接口的调用,就可能会带来更大的危害。而解决方案就是在App的shouldOverideUrlloading函数中对URL进行检查。

Android WebView 攻防指南-第15张图片-极光之门

最后要说的一种是利用竞争条件绕过URL校验的方式。这种绕过的特征是开发者仅对JsInterface API这个层级进行一个检查,同时它维护了一个WebView当前加载的URL。API对其进行URL检查,如果检查通过就返回特权接口的内容,如果检查不通过就拒绝执行。

Android WebView 攻防指南-第16张图片-极光之门

大家可以看到,这个跳转函数如果开发者使用了跳转的域名,也就是用第二个url参数去设置WebView当前要加载的URL的话,就会存在一个条件竞争的漏洞。这个漏洞的形成原因在于攻击者是可以去控制WebView当前要加载的URL的,因为它是从跳转的过程中去取的,因此攻击者也可以控制这个当前加载的url。

Android WebView 攻防指南-第17张图片-极光之门

这段代码的原理在于JS放在攻击者可控的网页中,往白名单域名去跳转,通过跳转,一些函数会被回调,这个时候WebView当前要加载的URL就被改写成了白名单域名。但是这个页面还有一个时间窗口去销毁,在还没有销毁的间隙,Test函数可以反复尝试,是有机会成功执行的,如果成功执行就会去调用getToken窃取信息,这就是对竞争条件漏洞的利用。

Android WebView 攻防指南-第18张图片-极光之门

同时,WebView也可能会处理intent scheme,如果校验不严,就会存在一些Intent跳转的漏洞,比如攻击者可以去构建一个intent去指向受害APP自己的组件,或者受害APP有权限访问的组件,就会带来比较严重的launchAnyWhere问题。


说完了形形色色的URL校验问题,那么如何做好安全的URL校验呢?严格来说,CheckDomain的使用位置应该在WebView加载和跳转前,在JavascriptInterface接口中调用,这是针对安卓原生注解的JsInterface接口。如果只对接口级进行防御,可以采用JsBridge的接口,此时可以在JS的回调函数中去检查URL的参数,就可以避免我们之前所说的条件竞争的问题。

Android WebView 攻防指南-第19张图片-极光之门

这里我对URL的校验函数和Intent scheme校验都做了一些拆解。


另外,对于安全研究员和开发者来说,如果要对自己的WebView应用进行审计的话,以下是我列举的一些安全审计点。

Android WebView 攻防指南-第20张图片-极光之门

四.WebView安全防御

前面我们讲到了WebView的安全配置的白名单校验,里面的坑是非常多的。


那最后我就来讲讲WebView的安全防御,主要就是我们的APP开发者要构建一个安全SDK构建安全基线,包含了我们一些默认的安全的设置以及白名单的校验,可以通过云控进行下发


同时我们这个白名单校验可以有针对性地校验,并对权限进行分级,不同的白名单的页面应该有不同的能力。

Android WebView 攻防指南-第21张图片-极光之门

以上就是我对WebView安全的介绍。

五.总结

总结一下,今天我给大家介绍了WebView安全的历史问题、本地攻击面和远程攻击面、安全配置和使用以及形形色色的URL校验问题。


对于开发者而言,使用WebView的原则有以下几点:首先是内容可信,仅允许最小的域名或者有这个功能需求的域名让WebView加载。同时还要保证特权最小,并不是所有的接口都要开放,而是只使用所需要的接口。最后一个原则就是可以把一些WebView的默认配置和白名单校验封装到标准SDK中进行使用

标签: 安全 漏洞 WebView

发表评论 (已有0条评论)

还木有评论哦,快来抢沙发吧~