前言:
客戶僅提供官網下載地址給我們測驗,但是由于官網的版本不是最新的,APP會強制你升級,而升級后的APP,是進行加固后的,無法使用frida進行hook,注入行程,那同樣也無法使用SSL Unpinning進行限制客戶端校驗證書,新版app使用查殼軟體顯示未加殼,但是查看源代碼明顯少了很多代碼,且很多都是變數宣告而已,
繞過更新:
我們要想能對APP滲透測驗,一般都是需要抓包和解密的,首先使用burp進行抓包代理,官網版本的APP(以下統稱舊版APP),是可以輕松抓到APP的包的(該條請求為檢驗APP最新版本的請求),但是內容使用了加密,具體什么加密是不得而知,

獲取到請求密文:
vVAK0jos5eT9gmQJaHOaYbqZ1mgXoBH3bee3MTF3G5wNRHRoPPOYokZLT4MQqaPDN%2BLeEYpIzzDJeErDHcDfhY8muosLfOaw35W3BuCxDNtuNFB86RumMBtOcQXT08qw
回應包未json,urldecode后為:
{"duration":"0ms","note":"","code":1,"resultDES":"UX/jHk6yqix2yxZIrf0rSIuOjCy6oGxjCPUfBL2avG+DWy/++NW16+YQHVFQ+Nj2w9VOWGcH4OxFtGxbR6K7I6pY0Q9hkP9gc0K0JLZ5O+PwOW72nzissCiLG+cHqadKHzkPOQDdBUuBoa4W1Jz7fQ=="}
通過desStr和resultDES,一開始我猜測他為des加密,具體是不是,后續再說,
先進入APP,但是一進入APP就提示更新:

通過前言,我們知道是不能更新的,(當然不乏某些技術大佬也可以把新版APP搞定,我技術有限,感覺舊版的比較容易搞),那我們就明確了目標,要先繞過更新校驗,
對于不了解hook**和frida的同學,我這邊推薦先去網上了解下,還有安裝之類的,再來看此篇文章,
【----幫助網安學習,以下所有學習資料免費領!加vx:yj009991,備注 “博客園” 獲取!】
① 網安學習成長路徑思維導圖
② 60+網安經典常用工具包
③ 100+SRC漏洞分析報告
④ 150+網安攻防實戰技術電子書
⑤ 最權威CISSP 認證考試指南+題庫
⑥ 超1800頁CTF實戰技巧手冊
⑦ 最新網安大廠面試題合集(含答案)
⑧ APP客戶端安全檢測指南(安卓+IOS)
首先我們明確一下思路,要怎么繞過這個更新校驗呢?
(1)直接反編譯,修改APP的版本資訊為99.99之類的;
(2)通過修改版本驗證請求,使用http層面去繞過;
(3)使用hook,去重寫更新函式,或者繞過更新函式;
第一點要app能支持反編譯且不存在校驗簽名,第二點要能知道加密密文的密鑰,所以我選擇第三種:
通過jadx搜索更新,發現了兩處,成功獲取到源代碼,

類名分別為:com.xxxx.AppUpdate和com.xxxx.WelcomeActivity,通過代碼審計可以看到,是先呼叫的WelcomeActivity,WelcomeActivity再去呼叫的AppUpdate:

跟蹤進入AppUpdate,呼叫的checkNativeAppVersion():

通過上述代碼,我們可以看到,這邊就是用于判斷是否升級的函式,
public void onResponse(Call call, Response response) throws IOException { try { JSONObject jSONObject = new JSONObject(C.s2(new JSONObject(URLDecoder.decode(response.body().string(), DataUtil.UTF8)).getString("resultDES"), Config.WHITE_KEY, Config.IV.getBytes())); if (jSONObject.optInt("code", -1) > 0) { JSONObject optJSONObject = jSONObject.optJSONObject("object"); if (optJSONObject == null) { return; } if (WakedResultReceiver.CONTEXT_KEY.equals(optJSONObject.optString("isUpdate", ChatConfig.CARD_TYPE))) { nativeAppVersionInterface.updateApp(optJSONObject.optString("desc", "當前有新版本,是否需要更新"), optJSONObject.optString(ClientCookie.VERSION_ATTR, "")); } else { nativeAppVersionInterface.noUpdateApp(); } } else { nativeAppVersionInterface.showError(jSONObject.optString("note")); } } catch (JSONException e) { e.printStackTrace(); nativeAppVersionInterface.showError(e.getMessage()); } }
當JSONObject.optInt("code", -1) > 0時,是會去進行升級的,否則則執行nativeAppVersionInterface.noUpdateApp(),
這邊分析完后,其實我們就可以寫js進行hook操作了,
我們的hook思路可以這樣設定了:
重寫checkNativeAppVersion函式,執行執行nativeAppVersionInterface.noUpdateApp(),
Ps:因為我一開始直接重寫了checkNativeAppVersion,只執行了console.log(“enter checkNativeAppVersion”),沒有對APP進行啟動,這樣就會直接卡死在啟動頁,
附上js代碼:
if(Java.available){ console.log('success'); Java.perform(function(){ var appUpdate = Java.use("com.xxxx.AppUpdate"); appUpdate.checkNativeAppVersion.implementation = function(a,b,c,d,e,f){ console.log("enter AppUpdate");//判斷是否進入該hook函式,進入會執行該命令 f.noUpdateApp();//直接執行不需要更新函式,APP會自動進入 } }); }
使用命令:frida -U -l .\xxx.js -f 包名 --no-pause

成功進入:

解密:
已經成功進入該APP,但是如果想成功進行滲透測驗的話,還需要能解開APP的加密,通過des欄位,初步判斷為des加密,再回頭看看剛剛更新的那個請求,是有用c.s2()函式進行操作的,大概率s2就是解密函式,
JSONObject jSONObject = new JSONObject(C.s2(new JSONObject(URLDecoder.decode(response.body().string(), DataUtil.UTF8)).getString("resultDES"), Config.WHITE_KEY, Config.IV.getBytes()));
可以看到s2的三個引數,即前面回應包中的json欄位里面的resultDES引數,然后其次是Config.WHITE_KEY, Config.IV兩個引數,其中Config.IV是以位元組陣列的形式進行傳參的,通過跳轉可以看到組態檔的引數,

然后呢,因為獲取到密鑰和偏移量iv,這樣的話des就可以解了,但是問題是解不開,后續的思路就是如果可以直接hook這兩個加解密函式的話,是不是就可以不用管他的加解密了,

s1和s2函式不在java層,那我們就需要hook native層的代碼,Hook so檔案,首先我們先把安裝包后綴apk改成zip,然后解壓,就可以找到wkb-1.2.2.so的檔案了,(路徑為lib/arm64-v8a/wkb-1.2.2.so,前面的arm64根據自己測驗機的CPU架構進行選擇,)直接用ida打開,在匯出函式里面搜索des:

里面有很多des的相關函式,可使用以下js進行hook匯出函式:
if(Java.available){ console.log('success'); Java.perform(function(){ var point = Module.findExportByName("libwkb-1.2.2.so","desDecryptByteArray"); Interceptor.attach(point,{ onEnter: function(args){ console.log("Hook start"); console.log("args[0]=" + args[0]); //列印我們java層第一個傳入的引數 console.log("args[1]=" + args[1]); //列印我們java層傳入的第二個引數 }, onLeave: function(retval){ //onLeave: function(retval)是該函式執行結束要執行的代碼,其中retval引數即是回傳值 console.log("return:" + retval); //列印回傳值 } }); }); }
但是這邊很奇怪的是,通過函式findExportByName找到的地址都是為null,一開始以為是還沒加載到so檔案,但是后續進入APP后還是一樣為null,(有知道的大佬可以說下)

這就比較蛋疼了,得手動計算地址,首先先獲取so檔案的地址,看能不能獲取到,若不行,則表示未加載so檔案,
var soAddr = Module.findBaseAddress("libwkb-1.2.2.so");
console.log("soAddr:" + soAddr);

有地址出來,說明so檔案是存在的,可以正常呼叫,那么這邊就要去計算函式偏移量,之前在網上看到別人的一個公式:
函式地址=so**初始地址+函式偏移量+1**
但是我后面嘗試了好幾個,好像不同手機不同的計算方法,也可能我操作的有問題,我這邊的函式地址就是:
函式地址=so**初始地址+函式偏移量**
不用加一,我自己是用這個方法測驗計算的:找到一個匯出函式可以被查詢到的,比如我這邊使用的就是JNI_OnLoad函式:


獲取JNI_OnLoad的地址為0x79d5d7883c,然后使用這個地址減去so的地址:
0x79d5d7883c ? 0x79d5d67000 = 1183c
差值剛好為JNI_OnLoad的偏移量,所以我這邊就不用再進行加一操作了,
這樣我們就可以成功hook任意函式了,通過我一個個嘗試發現,以下函式一個都沒呼叫過:

然后呢,我查找了s2函式的用例,發現被decodeSm4的函式呼叫過,

我就嘗試了一下,hook了sm4EncryptByteArr:


附上js:
var soAddr = Module.findBaseAddress("libwkb-1.2.2.so"); var point = soAddr.add(0x136f0); Interceptor.attach(point,{ onEnter: function(args){ console.log("Hook start"); console.log("args[0]=" + args[0]); //列印我們java層第一個傳入的引數 console.log("args[2]=" + Java.vm.getEnv().getStringUtfChars(args[2], null).readCString()); //列印我們java層傳入的第三個引數 console.log("args[3]=" + Java.vm.getEnv().getStringUtfChars(args[3], null).readCString()); //列印我們java層傳入的第四個引數 }, onLeave: function(retval){ //onLeave: function(retval)是該函式執行結束要執行的代碼,其中retval引數即是回傳值 console.log("return:" + Java.vm.getEnv().getStringUtfChars(retval, null).readCString()); //列印回傳值 // retval.replace(0); //替換回傳值為0 // return retval; } });
Ps:通過ida里面的引數,我們可以看到第二個引數為類,我們就沒給他列印出來,
我人傻了,一開始的des字眼和偏移量這些都符合des的加密方式,誤導了我好久,一直往des方向去找,
尾聲:
其實很早我就已經解密成功了,直接通過java層,剛剛發現呼叫s2的decodeSm4函式,直接hook那邊即可成功獲取請求和回應的明文:

但是若通過js去操作修改數值,實在太麻煩了,要獲取密鑰和加密方式,通過腳本自動去加解密,所以我才會去hook native層,獲取到密鑰,因為上述密鑰Config.WHITE_KEY,其實是還有一層加密的,通過hook decodeWhiteKey函式的回傳值,成功獲取了密鑰,


其實后續我也嘗試去修改版本號繞過,但是事實證明,代碼存在驗簽:

可以看到,把版本號修改為99.9.99,成功繞過了更新檢測,但是他還存在一個盜版驗簽檢測:

驗簽代碼一樣需要用hook去繞過,所以前面說的方法一也是行不通的,然后我又突發奇想,有沒有可能他密文里面就包含版本資訊,那如果我使用99.9.99的版本,抓取密文,然后再安裝舊版APP,在他去請求版本更新時,替換密文,是不是可以繞過呢?經過嘗試,結果是:可以,他的版本校驗就是在服務端,這種方法也可以繞過,
總結:
不用輕易相信別人留下的資訊,還是得根據自己的分析得出結論,其實后續我一直在想為什么那個欄位是des呢,感覺之前是des加密,后續金融行業都進行了國密改造,然后欄位并未更改,導致這種現象,當然只是猜測,至此,已完成對這APP的抓包和加解密,
更多靶場實驗練習、網安學習資料,請點擊這里>>
合天智匯:合天網路靶場、網安實戰虛擬環境
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/533535.html
標籤:其他
上一篇:Prometheus
下一篇:MixGo CE主控板簡單介紹
