jiangwei212 发表于 2018-4-2 08:43

Android中WebView的跨域漏洞分析和应用被克隆问题情景还原(免Root获取应用沙盒数据)

本帖最后由 jiangwei212 于 2018-4-2 08:45 编辑

一、前言
去年年底支付宝的被克隆漏洞被爆出,无独有偶就是腾讯干的,其实真正了解这个事件之后会发现,感觉是针对支付宝。因为这个漏洞找出肯定花费了很大劲,主要是因为支付宝的特殊业务需要开启了WebView的跨域访问功能,导致了这个问题,其实Google官方的Android早期版本这个功能默认是开启的的确是个漏洞,但是最后的版本都默认关闭了,除非应用自己业务需要就开启。而支付宝的口令红包是利用了WebView进行操作的。同时开启了这个功能,腾讯应该是研究了很久的支付宝代码才分析出来的。不过就在过年前几天,阿里也爆出了腾讯微信的此类问题。其实现在很多app因为特殊业务需求会手动打开这个功能。但是这个功能开启的确有一定风险,而且非常严重。当然也不一定需要关闭这个功能,可以在WebView打开的时候做url安全检查也可以。后面分析这个漏洞就知道了。


当然本文不会针对支付宝问题来说这个问题,因为没必要而且支付宝也修复了,本文的目的在于把这个漏洞问题解释清楚,所以本文就自己写案例来介绍一下即可。主要包括服务端和客户端,客户端大家都知道不多说了,服务端之前我开发过JavaWeb,所以弄起来比较简单,这里不给出详细步骤。首先我们大致了解一下支付宝那个事件,支付宝有口令红包,在网页中会跳转到支付内部的WebView页面,这个主要利用了Android中自带的Activity启动协议scheme:
http://img.blog.csdn.net/20180225143316279?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamlhbmd3ZWkwOTEwNDEwMDAz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center

然后可以在网页html中通过链接app://www.wjdiankong.cn这样的形式打开我们的应用到这个Activity页面中。

二、漏洞情景还原
第一、构建客户端项目
下面就开始搭建构造案例项目,首先来构建一个客户端程序:
http://img.blog.csdn.net/20180225143639516?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamlhbmd3ZWkwOTEwNDEwMDAz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center

这里最主要的就是WebView这个Activity类,因为后面我们通过系统浏览器打开一个页面,通过协议链接打开跳转到这里:
http://img.blog.csdn.net/20180225143849399?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamlhbmd3ZWkwOTEwNDEwMDAz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center

这里我们内部是一个WebView,为了验证问题,就手动打开跨域访问开关,有两个方法可以操作。通过测试发现这两个方法随便打开一个都是可以复现问题的。然后就是通过跳转过来的链接携带想用WebView打开的url地址,一般这个地址就是包含恶意功能的网页,这里肯定就是利用跨域问题,把案例应用的沙盒数据的上传到指定服务器中。

第二、构建服务端项目
好了,客户端的项目构建成功了,下面就要构建服务端程序了,首先我们肯定要有一个可以让客户端浏览器打开的开始页面,然后就是接受恶意页面利用跨域问题获取到沙盒数据上传的接口,因为我之前弄过JavaWeb开发,所以操作起来比较简单,去Eclipse官网下载一个EclipseEE工具,然后新建一个工程即可:
http://img.blog.csdn.net/20180225150810792?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamlhbmd3ZWkwOTEwNDEwMDAz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center

点击新建,然后选择动态web项目:
http://img.blog.csdn.net/20180225150833332?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamlhbmd3ZWkwOTEwNDEwMDAz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center

我这里之前已经配置的tomcat目录了,首次会提示你选择服务器tomcat的目录,这个简单直接去apache官网下载一个压缩包,然后解压到本地目录即可。继续下一步直接完成:
http://img.blog.csdn.net/20180225150931263?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamlhbmd3ZWkwOTEwNDEwMDAz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center

默认是用Servlet作为业务逻辑处理功能的,比如接受客户端的get和post数据请求和下发功能的,然后就是全局的路径配置文件web.xml这个文件至关重要,当然还需要一个可以在客户端浏览器打开的页面openapp_up.html,这里我们只关心这个页面,另外一个页面先不管。然后还需要修改配置文件web.xml:
http://img.blog.csdn.net/20180225151104722?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamlhbmd3ZWkwOTEwNDEwMDAz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center

这里需要把编写逻辑的servlet配置路径访问即可。这里配置的路径是/fourborther/cloneApp,然后在来看看提供客户端浏览器打开的openapp_up.html页面内容:
http://img.blog.csdn.net/20180225151217531?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamlhbmd3ZWkwOTEwNDEwMDAz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center

这里看到就用一个链接,采用协议app://www.wjdiankong.cn打开我们之前客户端定义的MyWebViewActivyt页面,并且会带一个参数也就是恶意页面给内部的WebView加载,这个恶意页面内部就实现了本地沙盒数据的获取和上传功能,因为这个WebView已经开启了跨域访问功能了,所以恶意页面内部就可以从file域到http域的数据传递。注意:这里有个巨大的坑,导致我在这里耽误了两三天的时间,就是这里的恶意页面必须在手机本地,最好是sdcard目录下,不能在服务端,开始的时候我把恶意页面也放在了服务端,最后恶意页面中的跨域功能死活是不成功的,必须放在本地sd下面,所以我们还需要把恶意页面放到sd卡下面。

浏览器自动下载文件问题说明
说到这里得插播一个信息了,就是可以看到腾讯公布这个漏洞的时候,说到一个细节,就是他其实还需要借助Chrome的一个漏洞,就是可以自动下载保存一个文件到sd卡的目录下,这个漏洞就是设置了头部信息:
http://img.blog.csdn.net/20180225151753011?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamlhbmd3ZWkwOTEwNDEwMDAz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center

我们这里新建一个AutoDown.jsp功能,然后再内部添加这两行java代码,在去手机端用Chrome浏览器访问会发现:
http://img.blog.csdn.net/20180225152307897?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamlhbmd3ZWkwOTEwNDEwMDAz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center

就会提示你是否下载这个文件,点击下载就将上面的print内容保存到本地 /SD/Download/cloneapp_up.html 中了:
http://img.blog.csdn.net/20180225152400619?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamlhbmd3ZWkwOTEwNDEwMDAz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center

而对于其他浏览器就不是这个目录了,因为浏览器会修改这个保存路径,比如360浏览器的路径是:
http://img.blog.csdn.net/20180225152453400?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamlhbmd3ZWkwOTEwNDEwMDAz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center

所以这里会看到,如果想把这个恶意页面弄到sd卡下面,借助这个浏览器下载功能,还需要用户授权,做不了静默的。所以会看到这个操作是上面漏洞问题复现的前提,当然只要能把这个恶意页面弄到本地就好,还有其他方式都可以。但是这种方式看来最靠谱,因为网页很多可以利用的页面,我们只要做个钓鱼页面,很多小白用户都会选择下载的。
好了说了很多了,继续回来我们的主题,上面已经介绍了把恶意页面通过浏览器会下载到本地的,然后把路径携带给有问题漏洞的案例应用利用WebView打开,下面就来看看这个恶意页面内部到底是如何跨域访问沙盒数据的:
http://img.blog.csdn.net/20180225152853669?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamlhbmd3ZWkwOTEwNDEwMDAz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center

其实这个恶意页面内容是本文的重点,这里利用ajax先访问本地的沙盒数据内容,也就是用file协议,我们知道有很多域和协议的,本地域file大家都知道可以在浏览器中利用这个协议打开本地文件夹,比如:
http://img.blog.csdn.net/20180225153124609?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamlhbmd3ZWkwOTEwNDEwMDAz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center

而且有很多同学好奇uri和url的区别,这里就可以看出来,url专指网络协议,而uri包括所有的域协议,只要类似于这样的格式xxx://xxx.xxx等。所以这里看出url是uri的子集,所以这里因为WebView开启了跨域功能,所以利用ajax借助file协议就可以访问到本地沙盒数据,而应用自己访问自己的沙盒数据也是可以的,拿到数据时候就在上传到服务器中,接下来看看服务器接受代码:
http://img.blog.csdn.net/20180225153425265?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamlhbmd3ZWkwOTEwNDEwMDAz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center

这个代码从网上拷贝的,就是接受文件上传功能,在post方式中进行处理即可。接受恶意页面中上传的二进制数据,也就是应用的沙盒数据。然后我们把服务端项目运行起来:
http://img.blog.csdn.net/20180225160249246?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamlhbmd3ZWkwOTEwNDEwMDAz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center

在控制台看到这样的信息表示成功启动服务器了:
http://img.blog.csdn.net/20180225160316089?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamlhbmd3ZWkwOTEwNDEwMDAz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center

然后我们在浏览器中访问页面看看是否成功:
http://img.blog.csdn.net/20180225160334798?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamlhbmd3ZWkwOTEwNDEwMDAz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center

服务器tomcat默认端口就是8080,看到成功了,为了能够让手机端访问成功,我们需要把电脑和手机连接在同一个网段,然后获取电脑的ip地址,把localhost换成ip地址即可在手机端浏览器访问了。

三、漏洞攻击演示
到这里其实我们把所有的项目都搭建完成了,流程有点复杂,这里画个图说明一下吧:
http://img.blog.csdn.net/20180225160515417?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamlhbmd3ZWkwOTEwNDEwMDAz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center

这张图世界独一无二,应该很清楚的介绍了跨域漏洞问题,下面就来还原一个恶意者利用这个漏洞获取用户手机中应用的沙盒数据信息:小白用户用Chrome浏览器浏览网页,正好被被恶意者的钓鱼链家命中了,他点击了恶意值的页面链接比如是:http://xxx.xxx.cloneapp.jsp;然后这链接内部会下载一个恶意html到sd卡下面,小白用户也不知道就随手点击下载了,这时候恶意的html页面就下载到sd下面了xxx.html,然后在cloneapp.jsp中还有其他链接可以打开有跨域漏洞的应用A,比如<a href=“app://xxx.xxx?url=file:///sdcard/Download/xxx.html>好看的,赶快点击</a>;用户点击就跳转到了A应用的WebView页面,正好A应用的这个页面接受url这个参数,这个需要反编译分析A应用才知道,不然恶意者没法传递参数。然后A应用就用WebView加载了sd卡的xxx.html页面,xxx.html中包含了访问沙盒数据并且传到服务端中的功能。
下面就来用案例演示漏洞场景,这里为了方便哈,就手动把上面的恶意页面cloneapp_up.xml直接手动放到sd卡下面了,因为上面的AutoDown.jsp中的自动下载内容,需要写入恶意页面很多内容,操作太费劲了,后面给出代码同学可以自己操作吧:
http://img.blog.csdn.net/20180225163343345?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamlhbmd3ZWkwOTEwNDEwMDAz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center

这里通过手机的浏览器输入http://192.168.253.1:8080/CloneApp/openapp_up.html页面,其中192.168.253.1是我的电脑ip地址。你们需要自己查看替换就好。访问这个页面就会通过协议打开本地的案例应用,然后利用内部的WebView加载已经存在sd卡的恶意页面cloneapp_up.html,然后cloneapp_up.html会把应用沙盒中的account.xml内容上传到服务器中:
http://img.blog.csdn.net/20180225163413073?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamlhbmd3ZWkwOTEwNDEwMDAz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center

这是案例应用的WebView加载恶意页面访问到沙盒xml数据信息,服务端也成功接收到了:
http://img.blog.csdn.net/20180225163510117?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamlhbmd3ZWkwOTEwNDEwMDAz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center

这个xml值是案例客户端程序启动的时候写入的用户名和密码:
http://img.blog.csdn.net/20180225164052173?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamlhbmd3ZWkwOTEwNDEwMDAz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center

四、漏洞总结
所以到这里,我们可以看到就WebView的跨域漏洞问题就完美还原了,可以看到操作步骤还是很麻烦的,但是可以利用一个恶意钓鱼页面就把手机中的某个具备跨域漏洞的应用沙盒账号信息上传到服务器了,还是很恐怖的。下面就来梳理一下吧:客户端程序:包括一个支持链接协议打开的页面,这个页面会解析协议带过来的一个参数url,然后内部用开启跨域漏洞问题的WebView加载这个url字段值。链接协议为:app://www.wjdiankong.cn服务端程序:包括钓鱼页面用于客户端用户使用浏览器访问,用户访问这个页面之后就会自动下载恶意页面html到sd卡中,并且该页面中有一个钓鱼链接可以协议打开客户端的页面把恶意页面的地址传递过去。客户端接收到参数就用自己的WebView打开这个恶意页面了,恶意页面内部利用跨域把客户端程序的沙盒数据上传到了恶意者服务器中。通过上面的案例流程也可以发现这个漏洞的危害性很大,恶意者只要借助一个钓鱼页面就把手机中某个具备跨域漏洞的应用沙盒数据比如账号信息上传到自己的服务器了,比如支付宝就开启了跨域漏洞功能,而且包含一个具备协议打开的页面H5WebView,所以支付宝会被干。的确存在这样的问题。支付宝的沙盒数据敏感信息都会被窃取。但是我们也发现这个漏洞利用过程,恶意者必须先分析客户端程序:恶意者在操作之前必须先要反编译案例应用分析他的沙盒数据结构(数据库名,xml名等),以及支持协议打开的WebView页面传递的参数信息,不然是没法操作的。所以腾讯爆出支付宝的这个问题,肯定反编译支付宝研究了他的代码逻辑。

上面跨域漏洞就分析完了,其实说白了就是因为应用使用WebView的时候,因为特殊业务手动开启了跨域功能:mWebView.getSettings().setAllowUniversalAccessFromFileURLs(true);
mWebView.getSettings().setAllowFileAccessFromFileURLs(true);
跨域就是从file本地域到网络的跨接这么理解。本身ajax是不支持跨域访问,所谓的跨域是指域名不一样就是跨域,比如http://aaa.bbb.com到http://bbb.aaa.com就是跨域操作,而这里看到不仅域名协议都不一样,跨的有点大了。

五、应用克隆问题
那么这个漏洞和支付宝的应用克隆技术有什么关系呢?什么叫克隆技术呢?其实上面我们看到已经把应用的沙盒账号信息都弄到自己的服务器了,那么恶意者在自己的设备在去自己的服务器获取这个账号信息,然后替换同应用的沙盒信息,不就实现了应用克隆吧,恶意者把不知道在地球的哪个地方的人的同一个应用的账号信息给克隆到自己的同一个应用账号中。这个过程有一个小问题就是恶意者如何把服务器的账号信息同步到自己的应用中呢?其实我们看腾讯的演示视频并没有看懂怎么操作的?我原想着把上面的file和http操作反过来,恶意者只需要在自己的设备浏览器打开一个页面实现逆向操作,把服务端的数据在跨域同步到本地。但是我操作失败了。不过没关系,因为数据已经到了恶意者的服务器中了,想克隆同步就很简单了,比如恶意者可以把手机root了,然后写个程序先去自己服务器获取数据,然后借助root权限强制把数据写入到同一个应用中,这样也可以实现克隆了。恶意者不在乎root等操作。他在意的是能够克隆成功就好。

六、总结
本文通过复杂的操作把WebView的跨域漏洞情景完美还原复现了,整个操作可以看到非常麻烦,复现这个漏洞付出很多,只是为了能够给你们讲解清楚。自己在项目中用到WebView一定要注意这个操作。欢迎购买本人逆向大黄书「Android应用安全防护和逆向分析」

李世民 发表于 2018-5-24 14:53

新闻上说只要点击就会被克隆,我在想这个感染律可是相当恐怖的,但这么完美感觉不真实,看了此文才知道还要用谷歌浏览器还要点击下载保存才能实现,ccav的新闻也不靠谱。

jinxuchao 发表于 2018-4-2 09:12

感谢分享

zhangD 发表于 2018-4-2 09:28

很详细的教程,大赞

Loopher 发表于 2018-4-2 09:43

四哥,很赞很赞

gsj000 发表于 2018-4-2 09:56

很详细的教程,大赞

戏言19 发表于 2018-4-2 10:16

讲得挺清楚了&#128077;

kanxue2018 发表于 2018-4-2 10:23


很详细的教程,大赞

yssun 发表于 2018-4-2 10:26

很详细的教程,大赞

CJTRAND 发表于 2018-4-2 10:42

生死看淡,不服就干!

wuai920981023 发表于 2018-4-2 10:59

看不懂啊
页: [1] 2 3 4 5 6 7
查看完整版本: Android中WebView的跨域漏洞分析和应用被克隆问题情景还原(免Root获取应用沙盒数据)