Android——反编译某互联网金融APP,通过JS漏洞获取用户信息、调用分享接口植入钓鱼网站(安全篇)

2,733 阅读4分钟

本文将分为三部分进行详细讲解:

  1. JavaScript和WebView通信的基本使用方法;

  2. 通过反编译,快速定位攻击路径,调用JS接口获取用户信息、植入钓鱼网站;

  3. 解决办法; 结果如下:

    在这里插入图片描述

在这里插入图片描述
众所周知,H5+JS接口+Webview这种混合开发模式十分普遍,市场上面绝大部分应用或多或少都是用了。

本文实例讲解的是当前市场上用户量较大的一款互联网金融APP,注册用户数几百万,流水达几十亿。在本文之前已经将漏洞告知对方,这里为了保密不提及应用名称,包名。

优点如下:

1.开发快捷,维护方便,由于页面采用的是H5,所以版本兼容性也比较好;

2.有效的减小apk的大小,别小看这点,当项目apk大小达到100M左右,减小apk体积就是一个很重要的KPI了;

3.适合数据开放,接入合作方的H5页面,在APK内调用对外的JS接口获取apk内的开放数据;

4.如果在webview里面设置好缓存,离线包等加载方式加载速度体验也挺好的;

缺点:

虽然讲述了需多优点,但是有一个致命的安全问题需要引起大家的格外注意,那就是对外暴露的JS接口如果没有严格的健全机制很容易被恶意调用,泄漏用户的隐私数据、或者调用接口植入钓鱼网站。

  1. 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通信的基本使用方法

  1. 通过反编译,快速定位攻击路径,调用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. 解决办法 1.对于webview来说,添加url白名单,不在白名单里面的地址不加载或者不进行注入java对象; 2.对接口的访问权限进行分级,添加鉴权功能; 3.暴露的组件也可以对传入的scheme url进行校验,增加攻击者的难度等等

如果您还有更好的解决办法,欢迎留言。