本文将分为三部分进行详细讲解:
-
JavaScript和WebView通信的基本使用方法;
-
通过反编译,快速定位攻击路径,调用JS接口获取用户信息、植入钓鱼网站;
-
解决办法; 结果如下:
本文实例讲解的是当前市场上用户量较大的一款互联网金融APP,注册用户数几百万,流水达几十亿。在本文之前已经将漏洞告知对方,这里为了保密不提及应用名称,包名。
优点如下:
1.开发快捷,维护方便,由于页面采用的是H5,所以版本兼容性也比较好;
2.有效的减小apk的大小,别小看这点,当项目apk大小达到100M左右,减小apk体积就是一个很重要的KPI了;
3.适合数据开放,接入合作方的H5页面,在APK内调用对外的JS接口获取apk内的开放数据;
4.如果在webview里面设置好缓存,离线包等加载方式加载速度体验也挺好的;
缺点:
虽然讲述了需多优点,但是有一个致命的安全问题需要引起大家的格外注意,那就是对外暴露的JS接口如果没有严格的健全机制很容易被恶意调用,泄漏用户的隐私数据、或者调用接口植入钓鱼网站。
- JavaScript和WebView通信的基本使用方法;
webview的设置
//首先允许webview执行js脚本
settings.setJavaScriptEnabled(true);
//给webview注入一个java对象供H5的JS调用其对外的方法
mWebView.addJavascriptInterface(new JSObject(),"JavascriptInterface");
复制代码
注入的java对象里面增加H5调用的方法
public class JSObject {
@JavascriptInterface
public void getAppInfo(String param1,String param2){
}
}
复制代码
H5调用Native方法示例:
<script type="text/javascript">
//提供给Native侧调用
function say(text) {
alert(text)
}
function getResult(message) {
return message;
}
//调用Native侧的接口
function getNativeAppInfo(){
window.JavascriptInterface.getAppInfo()
}
</script>
复制代码
Native调用H5的函数进行传值
方法一:
webView.loadUrl("javascript:say(\"" + "xxxxxxxxxx" + "\")");
方法二:
webView.evaluateJavascript("getResult(\""+"xxxxx'"+"\")", new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
Log.i(TAG, "onReceiveValue value=" + value);
}
});
复制代码
以上就是JavaScript和WebView通信的基本使用方法
- 通过反编译,快速定位攻击路径,调用JS接口获取用户信息、植入钓鱼网站
反编译步骤:
1.java -jar apktool_2.3.3.jar d -f xxx.apk
使用apktool这个工具将一个apk反编译得到图片、XML配置、语言资源等文件。
2. sh d2j-dex2jar.sh classes.dex
获取classes-dex2jar.jar
3. 使用java -jar jd-gui-1.4.0.jar 查看源码
复制代码
我们通过反编译查看AndroidManifest文件,查找scheme关键字,看下该应用对外暴露了哪些组件同时可以通过scheme拉起来。 和大部分APP一样,该金融APP的Splash页面允许被外部拉起。
<activity android:name="com.xxxxx.SplashScreenActivity" android:screenOrientation="portrait" android:theme="@style/SplashTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:host="xxxhost" android:pathPrefix="/openwith" android:scheme="xxxschemeapp"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="xxxscheme"/>
</intent-filter>
</activity>
复制代码
然后我们反编译查看代码,虽然代码被混淆过了,但是并不阻碍我们阅读它的逻辑:
我们发现在识别出scheme头之后,进行了url的加载,gotoUrl()函数。 然后我们再看下加载Url的webview部分代码是否有注入Java对象,是否有提供数据的JS接口: 果不其然,注入了JsObject类,我们查看该类: 基本上该类对外提供了一个JS接口,然后通过第一个参数执行不同的代码逻辑,类似命令模式; 然后我们找到想要的接口第一个参数是什么下面这个接口就是文章的第一个截图,获取App的用户数据其中还包括手机号码
下面这个截图即是分享弹出分享按钮,分享url的接口,通过此接口可以植入一个钓鱼网站分享到微信,微博,QQ等,由于有官方的应用icon,用户很容易被欺骗到,输入敏感数据: 最后我们只需要在在H5代码中调用这两个接口即可,这里参考第一部分的基本原理,不贴示例代码了。另外: 由于scheme是可以被浏览器拉起的,还可以直接将组装好的scheme链接加入到一些网页的超链接,用户点击之后直接拉起该应用,具有远程攻击的可行性。
其实整体的思路就是找到暴露的组件,反编译之后如何传参,然后找到相关的JS接口,这样一个攻击路径就找到了。
- 解决办法 1.对于webview来说,添加url白名单,不在白名单里面的地址不加载或者不进行注入java对象; 2.对接口的访问权限进行分级,添加鉴权功能; 3.暴露的组件也可以对传入的scheme url进行校验,增加攻击者的难度等等
如果您还有更好的解决办法,欢迎留言。