安卓APP測試之HOOK大法
一般測試 APP 都是先設定代理,然後抓包進行測試。但是大多數情況下,抓取的資料包都含有引數校驗,一旦修改其中一個引數之後,就會返回簽名錯誤。
例如 :
還有的有時間校驗,當過去某一時間段後,該資料包就失效了。
因此如果想要去重放或者修改資料包進行 FUZZ 的話,就要弄清楚其中的加密 sign 值的演算法。
本文以某 app 老版本為例 ( 僅為技術研究 ) ,主要目的是利用 Frida 進行 HOOK 進而去獲取其 api -sign 的加密演算法。
0x02 環境準備
這裡手機採用 魅 族 X4 ,刷了 CM13.0 ,開啟 ROOT 許可權。
APP 版本為 v3.0.10 ,下載地址:
https://www.wandoujia.com/apps/cn.soulapp.android/history_v18080100
然後就是 Frida 環境的準備了 。
Frida 是一款基於 Python + JavaScript 的 Hook 與除錯框架,在 AndroidLinuxWindows 等平臺均能使用。這裡我們以 Windows 來對 Android 應用程式進行 Hook 。 Frida 的官網地址是: https://www.frida.re 。
安裝方法也很簡單 :
pip install frida -tools
手機開啟開發者模式,並開啟 USB 除錯。
下載 frida-server ,下載地址為:
http://build.frida.re/frida-snapshot/android/arm/bin/frida-server 。
上傳到手機
adb push frida -server /data/local/ tmp /
新增許可權
root@mx4:/ # chmod 777 frida -server
手機上執行 frida-server ,命令如下 :
root@mx4:/ #./ data/local/ tmp / frida -server
埠轉發 , 電腦上執行如下命令 :
adb forward tcp:27042 tcp:27042
環境準備好了,就開始對 APP 進行測試 。
0x03 利用 Frida 進行 HOOK
安裝後開啟 APP 。
發現 APP 閃退,並提示 SoulApp 暫不支援模擬器,請稍後再試 ~ 。
用 jadx 開啟 apk 檔案,搜尋關鍵字 模擬器 。
只有一處,我們點進去。
其中有個判斷,如果 cn.soulapp .android.utils.j.e() 為 true ,則提示不支援模擬器,並退出程式。點進這個方法檢視。
其中有多個判斷,如果一個為 true ,則返回 true ,最簡單有效的方法就是 hook ,直接令返回為 false 。 使用 Frida 進行 hook ,程式碼如下 :
執行後,發現再次開啟 app ,可以順利進入了。
輸入手機號,點選確定。
提示 網路錯誤 ,這是因為使用了代理,所以報錯,但是有資料包的。可以暫時先不管這裡。我們目的是獲取 sign 值的加密演算法。這裡是獲取 api -sign 的加密演算法。
資料包內容
資料包中有 api-sign ,所以直接利用 jadx 搜尋 api-sign 。
發現在 cn.soulapp.android.api.b. b.b () 中有呼叫,進入檢視 。
api-sign 值的獲取呼叫了 cn.soulapp.android.api.b. c.a 方法 。
這裡是建立了一個 stringBuilder ,經過拼接後,呼叫 com.gongjiao .rr.tools.f.b 進行 sha1 加密,並轉換為大寫。我們需要知道 cn.soulapp.android.api.b.c.a 三個引數的值是什麼。
aVar.b (" api -sign", c.a ( aaVar , replaceAll , currentTimeMillis ));
根據程式碼可以推測,第一個引數 aaVar 是類 okhttp3.Request 的例項化;
第二個引數 replaceAll 是獲取的 UUID 去除中間的 "-" ;
第三個引數是當前時間戳減去 cn.soulapp.android.api. a.a () 。這個值是從 soul_share.xml 中讀取 ApiConstants_timeDiff 的值,檢視 soul_share.xml 發現內容為空。
所以第三個引數為當前的時間戳。
檢視 cn.soulapp.android.api.b.c.a 方法,前半部分是對 aaVar 進行操作,大概是獲取請求的路徑,然後對引數進行拼接。
看後半部分的程式碼 :
這裡第71行中的UTDevice.getUtdid(SoulApp.b())為裝置號,即資料包裡面的device-id;
第72行的a.j為固定值,這裡為10000003;
第73行這個值需要獲取,可以用hook獲取;
第74行a(j)是將傳入的時間戳(第三個引數)進行轉換;
第75行是拼接了傳入的第二個引數;
第78行拼接了固定值3010;
然後第80行呼叫com.gongjiao.rr.tools.f.b對stringBuilder進行加密,並轉換為大寫。
可以通過 hook 的方法直接獲取 cn.soulapp.android.api.b. c.a 和 com.gongjiao.rr. tools.f.b 的引數。
主要程式碼 :
由於 cn.soulapp.android.api.b.c 中有多個 a 方法,所以這裡用了過載,指明引數型別來確定是哪個方法。
執行效果
知道了加密演算法以及引數,就可以自己實現加密獲取 api -sign 了,如下所示:
api -sign 值可以獲取了,我們試一下能否利用。由上面知道 代理抓 包時資料包返回 400 ,經過檢視程式碼是可以解決這個問題的。 這裡不詳細說明 。
發現該方法獲取 api -sign 是可行的。
0x04 其他問題
1. 不進行 hook 獲取引數的內容或者檢視呼叫堆疊的方法
可以通過動態除錯的方法進行檢視。
首先將 apk 反編譯為 smali 檔案,然後 IDEA 安裝 smalidea 外掛。下載地址: https://bitbucket.org/JesusFreke/smali/downloads/
反編譯的命令如下 :
java -jar baksmali-2.2.2.jar d 106_3ce8a91b116f3ca28175affa3d12083f.apk -o SoulApp3010/ src
然後匯入到 idea 中
然後在需要檢視的地方下斷點。
例如在 cn.soulapp.android.api.b. c.a 下斷點
開啟 Run /Debug Configurations ,新增一個遠端除錯,埠 8700
執行 app ,然後在 Android Device Monitor 中選中
開啟除錯按鈕,點選手機上的確定,進入除錯。
2. 加密的演算法在 so 檔案中
簡單的方法就是獲取呼叫 so 中方法的引數,然後自己寫一個 app ,呼叫其 so 檔案。
如果有判斷的話,可以修改 so 檔案達到可以呼叫的目的。
如上所示,該 so 檔案有判斷,如果 isInMyAPP 為 false ,則會退出,返回 null 。
我們可以修改 CMP R0,#0 為 CMP R0,#1 來繞過該限制。
修改後
更深入的就是對 so 檔案進行分析,找到其中的加密演算法。
0x05 總結
Frida 不僅可以用於 hook java 層,也可以進行 native 層的 hook 。利用 Frida 進行 hook 時,要求需要使用已 ROOT 的手機,對於手機無法 ROOT 的,安裝 VirtualXposed 後使用 Xposed 框架也可以進行 HOOK 。這裡就不說明了,有興趣的可以去試一試。