2024年3月5日发(作者:)
android WebView详解,常见漏洞详解和安全源码(下)
WebView 常见漏洞
WebView 的漏洞也是不少,列举一些常见的漏洞,实时更新,如果有其他的常见漏洞,知会一下我~~
WebView 任意代码执行漏洞
已知的 WebView 任意代码执行漏洞有 4 个,较早被公布是 CVE-2012-6636,揭露了
WebView 中 addJavascriptInterface 接口会引起远程代码执行漏洞。接着是
CVE-2013-4710,针对某些特定机型会存在 addJavascriptInterface API 引起的远程代码执行漏洞。之后是 CVE-2014-1939 爆出 WebView 中内置导出的 “searchBoxJavaBridge_” Java
Object 可能被利用,实现远程任意代码。再后来是 CVE-2014-7224,类似于
CVE-2014-1939 ,WebView 内置导出 “accessibility” 和 “accessibilityTraversal” 两个 Java
Object 接口,可被利用实现远程任意代码执行。
一般情况下,WebView 使用 JavaScript 脚本的代码如下所示:
WebView mWebView = (WebView)findViewById(w);
WebSettings msetting = tings();
aScriptEnabled(true);
ascriptInterface(new TestJsInterface(), “testjs”);
l(url);
CVE-2012-6636 和 CVE-2013-4710
Android 系统为了方便 APP 中 Java 代码和网页中的 Javascript 脚本交互,在
WebView 控件中实现了 addJavascriptInterface 接口,如上面的代码所示,我们来看一下这个方法的官方描述:
This method can be used to allow JavaScript to control the host application. This is a powerful
feature,
but also presents a security risk for apps targeting JELLY_BEAN or earlier. Apps that target a
version
later than JELLY_BEAN are still vulnerable if the app runs on a device running Android earlier
than 4.2.
The most secure way to use this method is to target JELLY_BEAN_MR1 and to ensure the
method is called
only when running on Android 4.2 or later. With these older versions, JavaScript could use
reflection
to access an injected object's public fields. Use of this method in a WebView containing
untrusted
content could allow an attacker to manipulate the host application in unintended ways, executing
Java
code with the permissions of the host application. Use extreme care when using this method in a
WebView
which could contain untrusted content.
JavaScript interacts with Java object on a private, background thread of this WebView. Care is
therefore
required to maintain thread Java object's fields are not accessible.
For applications targeted to API level LOLLIPOP and above, methods of injected Java objects are
enumerable from JavaScript.
可以看到,在 JELLY_BEAN(android 4.1)和 JELLY_BEAN 之前的版本中,使用这个方法是不安全的,网页中的JS脚本可以利用接口 “testjs” 调用 App 中的 Java 代码,而 Java 对象继承关系会导致很多 Public 的函数及 getClass 函数都可以在JS中被访问,结合 Java 的反射机制,攻击者还可以获得系统类的函数,进而可以进行任意代码执行,首先第一步 WebView 添加 Javascript 对象,并且添加一些权限,比如想要获取 SD 卡上面的信息就需要 _EXTERNAL_STORAGE ;第二步 JS 中可以遍历
window 对象,找到存在 getClass 方法的对象,再通过反射的机制,得到 Runtime 对象,然后就可以调用静态方法来执行一些命令,比如访问文件的命令;第三步就是从执行命令后返回的输入流中得到字符串,比如执行完访问文件的命令之后,就可以得到文件名的信息了,有很严重暴露隐私的危险,核心 JS 代码:
function execute(cmdArgs)
{
for (var obj in window) {
if ("getClass" in window[obj]) {
alert(obj);
return window[obj].getClass().forName("e")
.getMethod("getRuntime",null).invoke(null,null).exec(cmdArgs);
}
}
}
所以当一些 APP 通过扫描二维码打开一个外部网页的时候,就可以执行这段 js 代码,漏洞在 2013 年 8 月被披露后,很多 APP 都中招,其中浏览器 APP 成为重灾区,但截至目前仍有很多 APP 中依然存在此漏洞,与以往不同的只是攻击入口发生了一定的变化。另外一些小厂商的 APP 开发团队因为缺乏安全意识,依然还在APP中随心所欲的使用
addJavascriptInterface 接口,明目张胆踩雷。
出于安全考虑,Google 在 API17 版本中就规定能够被调用的函数必须以
@JavascriptInterface 进行注解,理论上如果 APP 依赖的 API 为 17(Android 4.2)或者以上,就不会受该问题的影响,但在部分低版本的机型上,API17 依然受影响,所以危害性到目前为止依旧不小。关于所有 Android 机型的占比,可以看看 Google 的 Dashboards:
截止 2017/1/9 日,可以看到 android5.0 之下的手机依旧不少,需要重视。
漏洞的解决
但是这个漏洞也是有解决方案的,上面的很多地方也都提到了这个漏洞,那么这个漏洞怎么去解决呢?这就需要用到 onJsPrompt 这个方法了,这里先给出解决这个漏洞的具体步骤,在下面的源码部分有修复这个漏洞的详细代码:
继承 WebView ,重写 addJavascriptInterface 方法,然后在内部自己维护一个对象映射关系的 Map,当调用 addJavascriptInterface 方法,将需要添加的 JS 接口放入这个 Map
中;
每次当 WebView 加载页面的时候加载一段本地的 JS 代码:
javascript:(function JsAddJavascriptInterface_(){
if(typeof(_js_interface_name)!='undefined'){
('_js_interface_name is exist!!');
}else{
_js_interface_name={
XXX:function(arg0,arg1){
return
prompt('MyApp:'+ify({obj:'XXX_js_interface_name',func:'XXX_',args:[arg0,arg1]}));
},
};
}
})()
这段 JS 代码定义了注入的格式,其中的 XXX 为注入对象的方法名字,终端和 web
端只要按照定义的格式去互相调用即可,如果这个对象有多个方法,则会注册多个
_js_interface_name 块;
然后在 prompt 中返回我们约定的字符串,当然这个字符串也可以自己重新定义,它包含了特定的标识符 MyApp,后面包含了一串 JSON 字符串,它包含了方法名,参数,对象名等;
当 JS 调用 XXX 方法的时候,就会调用到终端 Native 层的 OnJsPrompt 方法中,我们再解析出方法名,参数,对象名等,解析出来之后进行相应的处理,同时返回值也可以通过 prompt 返回回去;
_js_interface_name 代表在 window 上声明了一个对象,声明的方式是:方法名:function(参数1,参数2)。
还有一个问题是什么时候加载这段 JS 呢,在 WebView 正常加载 URL 的时候去加载它,但是会发现当 WebView 跳转到下一个页面时,之前加载的 JS 可能就已经无效了,需要再次加载,所以通常需要在一下几个方法中加载 JS,这几个方法分别是
onLoadResource,doUpdateVisitedHistory,onPageStarted,onPageFinished,onReceivedTitle,onProgressChanged。 通过这几步,就可以简单的修复漏洞问题,但是还需要注意几个问题,需要过滤掉 Object 类的方法,由于通过反射的形式来得到指定对象的方法,所以基类的方法也可以得到,最顶层的基类就是 Object,为了不把 getClass 等方法注入到 JS 中,我们需要把 Object 的共有方法过滤掉,需要过滤的方法列表如下:“getClass”,“hashCode”,“notify”,“notifyAll”,“equals”,


发布评论