本文將分為三部分進行詳細講解:
-
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進行校驗,增加攻擊者的難度等等
如果您還有更好的解決辦法,歡迎留言。