前言你不知道的 Android webView 使用漏洞。现在很多 App 里都内置了 Web 网页(Hyprid App),比如说很多电商平台,淘宝、京东、聚划算等等,如下图
上述功能是由
Android 的 WebView实现的,但是 WebView 使用过程中存在许多漏洞,容易造成用户数据泄露等等危险,而很多人往往会忽视这个问题 今天我将全面介绍
Android WebView 的使用漏洞及其修复方式目录
1. 类型 WebView 中,主要漏洞有三类: 任意代码执行漏洞 密码明文存储漏洞 域控制不严格漏洞 2. 具体分析 2.1 WebView 任意代码执行漏洞
出现该漏洞的原因有三个:
WebView 中
- addJavascriptInterface() 接口 WebView 内置导出的 searchBoxJavaBridge_对象 WebView 内置导出的 accessibility 和 accessibilityTraversalObject 对象
- 2.1.1 addJavascriptInterface 接口引起远程代码执行漏洞
- A. 漏洞产生原因
- JS调用Android的其中一个方式是通过addJavascriptInterface接口进行对象映射:
- webView.addJavascriptInterface(new JSObject(), "myObj"); // 参数1:Android的本地对象// 参数2:JS的对象// 通过对象映射将Android中的本地对象和JS中的对象进行关联,从而实现JS调用Android的对象和方法
- 所以,漏洞产生原因是:当JS拿到Android这个对象后,就可以调用这个Android对象中所有的方法,包括系统类(java.lang.Runtime 类),从而进行任意代码执行。
- 具体获取系统类的描述:(结合 Java 反射机制)
- Android中的对象有一公共的方法:getClass() ; 该方法可以获取到当前类 类型Class 该类有一关键的方法: Class.forName; 该方法可以加载一个类(可加载 java.lang.Runtime 类) 而该类是可以执行本地命令的
- 以下是攻击的Js核心代码:
- function execute(cmdArgs) { // 步骤1:遍历 window 对象 // 目的是为了找到包含 getClass ()的对象 // 因为Android映射的JS对象也在window中,所以肯定会遍历到 for (var obj in window) { if ("getClass" in window[obj]) { // 步骤2:利用反射调用forName()得到Runtime类对象 alert(obj); return window[obj].getClass().forName("java.lang.Runtime") // 步骤3:以后,就可以调用静态方法来执行一些命令,比如访问文件的命令getMethod("getRuntime",null).invoke(null,null).exec(cmdArgs); // 从执行命令后返回的输入流中得到字符串,有很严重暴露隐私的危险。// 如执行完访问文件的命令之后,就可以得到文件名的信息了。 } } }
- 当一些 APP 通过扫描二维码打开一个外部网页时,攻击者就可以执行这段 js 代码进行漏洞攻击。 在微信盛行、扫一扫行为普及的情况下,该漏洞的危险性非常大
- B. 解决方案
- B1. Android 4.2版本之后
- Google 在Android 4.2 版本中规定对被调用的函数以 @JavascriptInterface进行注解从而避免漏洞攻击
- B2. Android 4.2版本之前
- 在Android 4.2版本之前采用拦截prompt()进行漏洞修复。
- 具体步骤如下:
- 继承 WebView ,重写 addJavascriptInterface 方法,然后在内部自己维护一个对象映射关系的 Map;
- 每次当 WebView 加载页面前加载一段本地的 JS 代码,原理是:
- 让JS调用一Javascript方法:该方法是通过调用prompt()把JS中的信息(含特定标识,方法名称等)传递到Android端; 在Android的onJsPrompt()中 ,解析传递过来的信息,再通过反射机制调用Java对象的方法,这样实现安全的JS调用Android代码。
- 具体需要加载的JS代码如下:
- javascript: (function JsAddJavascriptInterface_() { // window.jsInterface 表示在window上声明了一个Js对象// jsInterface = 注册的对象名// 它注册了两个方法,onButtonClick(arg0)和onImageClick(arg0, arg1, arg2)// 如果有返回值,就添加上return if (typeof(window.jsInterface)!='undefined') { console.log('window.jsInterface_js_interface_name is exist!!');} else { window.jsInterface = { // 声明方法形式:方法名: function(参数) onButtonClick:function(arg0) { // prompt()返回约定的字符串// 该字符串可自己定义// 包含特定的标识符MyApp和 JSON 字符串(方法名,参数,对象名等) return prompt('MyApp:'+JSON.stringify({obj:'jsInterface',func:'onButtonClick',args:[arg0]})); }, onImageClick:function(arg0,arg1,arg2) { returnprompt('MyApp:'+JSON.stringify({obj:'jsInterface',func:'onImageClick',args:[arg0,arg1,arg2]})); }, }; } } )()// 当JS调用 onButtonClick() 或 onImageClick() 时,就会回调到Android中的 onJsPrompt ()// 我们解析出方法名,参数,对象名// 再通过反射机制调用Java对象的方法
- 关于该方法的其他细节
- 细节1:加载上述JS代码的时机
- 由于当 WebView 跳转到下一个页面时,之前加载的 JS 可能已经失效 所以,通常需要在以下方法中加载 JS:
- onLoadResource();doUpdateVisitedHistory();onPageStarted();onPageFinished();onReceivedTitle();onProgressChanged();
- 细节2:需要过滤掉 Object 类的方法
- 由于最终是通过反射得到Android指定对象的方法,所以同时也会得到基类的其他方法(最顶层的基类是 Object类) 为了不把 getClass()等方法注入到 JS 中,我们需要把 Object 的共有方法过滤掉,需要过滤的方法列表如下:
- getClass()hashCode()notify()notifyAl()equals()toString()wait()
就爱阅读 www.92to.com 网友整理上传, 为您提供最全的知识大全, 期待您的分享,转载请注明出处。
来源: http://www.92to.com/bangong/2017/03-22/19258534.html