WebView组件远程代码执行漏洞

       在android的sdk中封装了webView控件,在webView下有一个非常特殊的接口函数addJavascriptInterface,利用这个接口函数可实现穿透webkit控制android 本机。

简介

       Webview是Android用于浏览网页的组件,它的接口函数addJavascriptInterface可以实现网页JS与本地JAVA的交互,但是没有限制已注册JAVA类的方法调用,导致可以利用反射机制调用未注册的其它任何JAVA类。当Android用户访问恶意网页时,会被迫执行系统命令,如安装木马、盗取敏感数据等。

漏洞详情

构建一个使用Webview组件的程序

1. AndroidManifest.xml添加网络访问权限

1
<uses-permission android:name="android.permission.INTERNET"/>


2. activity_my.xml添加Webview控件

1
2
3
4
5
<WebView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/webView">

</WebView>

3. MainActivity.java添加关键代码

1
2
3
4
5
6
7
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// add webview func
WebView webview = (WebView)findViewById(R.id.webView);
webview.getSettings().setJavaScriptEnabled(true);
webview.loadUrl("http://info.idhyt.xyz/vultest/checkwebview.html");");


4. 测试页面

       webview漏洞测试页面
       webview漏洞利用页面

5. 测试结果

       在没有使用addJavascriptInterface接口函数的情况下,
也会存在远程代码执行漏洞,原因是webview组件默认调用”searchBoxJavaBridge_”对象。
       

       当使用addJavascriptInterface接口函数时,代码改为

1
2
3
4
5
6
7
8
9
WebView webview = (WebView)findViewById(R.id.webView);
webview.getSettings().setJavaScriptEnabled(true);
webview.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
webview.addJavascriptInterface(new test(), "test");
webview.loadUrl("http://info.idhyt.xyz/vultest/checkwebview.html");

class test{
//do something...
}

       测试结果
       

       可以看到,即便test类没有具体实现代码,也一样会触发漏洞。

漏洞检测

       通过编写静态扫描器过滤出可能存在问题的apk,方法是通过apktool将apk文件反编译成smali,之后进行暴力搜索关键字。
       


其中用到的几个关键的正则:

1
2
3
4
5
6
7
8
9
10
获取类名
r"^\.class.+(Lcom.+);"
获取所有method
r"(\.method[\s\S]*?\.end *method)"
获取method方法类型
r"^\.method.+ +(\w+) *\("
获取method中的.line
r"\.line([\s\S]*?)(?=(\.line))"
获取指定的调用函数
r"setJavaScriptEnabled|addJavascriptInterface"

防范

  • 使用removeJavascriptInterface(“searchBoxJavaBridge“)移除searchBoxJavaBridge对象
    1.重构WebView控件(WebViewEx)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.example.idhyt.webview;

import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.webkit.WebView;

/**
* Created by idhyt on 2015/4/28.
*/

public class WebViewEx extends WebView {
public WebViewEx(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
if (Build.VERSION.SDK_INT > 10 && Build.VERSION.SDK_INT < 17) {
removeJavascriptInterface("searchBoxJavaBridge_");
// removeJavascriptInterface("accessibility");
// removeJavascriptInterface("accessibilityTraversal");
}

}
}

2.修改系统解析XML中定义的属性回调方法(layout\activity_main.xml中)

1
2
3
4
<com.example.idhyt.webview.WebViewEx
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/webView" />

3.调用WebViewEx控件

1
2
3
4
5
6
7
8
9
10
11
12
13
public class MainActivity extends ActionBarActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WebViewEx webview = (WebViewEx)findViewById(R.id.webView);
webview.getSettings().setJavaScriptEnabled(true);
webview.loadUrl("http://info.idhyt.xyz/vultest/checkwebview.html");
}

// other function
}
  • 确保只在访问可信页面数据时才使用addjavascriptInterface。
  • 在调用Java对象方法前对参数进行检查,避免执行恶意操作。
  • 对于在4.2(API 17+)系统运行的应用,使用JavascriptInterface代替addjavascriptInterface。
  • 限制对于该接口的使用来源,只允许可信来源访问该接口。例如使用WebViewClient中的shouldOverrideUrlLoading()来对加载的URL进行检查。

参考

  1. Abusing WebView JavaScript Bridges
  2. WebView中接口隐患与手机挂马利用
  3. Android WebView的Js对象注入漏洞解决方案