之前寫過一篇某款app協(xié)議的簡單分析的文章,前一段時間有人說他們的協(xié)議更新了,所以抽出時間來學習一下。
一、準備工作
1、抓包
第一步還是抓包,通過對比我們發(fā)現(xiàn),在請求字段中新出現(xiàn)了一個newSign的字段,并且原來的sign也不是每次都會變化了。所以說明確實做了協(xié)議的更新。

2、定位代碼
通過sign和newSign關鍵字,可以輕松定位到代碼。先來看newSign值,就是一堆key-value的值,日志中很明顯的用了StringToSign來標明要加密的字符串,最后就是md5和AES加密了。

但是這里的AES加密放在native層去做了,需要后面進一步的分析。

至于sign值的計算很簡單,跟之前一樣,就不贅述了。

二、協(xié)議分析
1、代碼插樁
為了更清晰的看到加密前后的輸出,在這里手動插入了log。方法是構造一個log類,然后在需要的地方直接調(diào)用該方法。smali代碼如下:

通過插樁,記錄了幾條值,一會兒要用這幾條數(shù)據(jù)做驗證。

2、Frida Hook
其實通過Frida也可以實現(xiàn)打印這幾條記錄的值,而且比代碼插樁更方便一些。encode是導出函數(shù),可以直接調(diào)用。我們hook函數(shù)并打印輸入和輸出值,就是加密前后的值了。

3、so分析
打開so文件,發(fā)現(xiàn)so沒有加密混淆,方法名也很容易判別。直接定位到encode函數(shù)。

知道采用了AES_128_ECB_PKCS5Padding加密方式,還需要一個秘鑰,在j_getKey方法中做了一些加密操作來隱藏key值。因為啃不動匯編代碼,也不打算仔細看其中的細節(jié),所以決定采用動態(tài)調(diào)試的方法來得到key。
這里可以簡化一下,我們新建一個demo工程,把so文件拷貝到工程目錄下。
這里需要注意的下就是,采取了動態(tài)注冊的方式,我們把java類拷貝過來時需要創(chuàng)建同樣的路徑名稱。


然后我們就可以調(diào)式自己的app了。
4、Android 動態(tài)調(diào)試
4.1 開啟android_server,監(jiān)聽23946端口
先給android_server授權
$ adb shell /data/local/tmp/android_server
4.2 本地端口轉發(fā)
$ adb forward tcp:23946 tcp:23946
4.3 調(diào)試模式啟動程序
$ adb shell am start -D -n packageName/launchActivity
4.4 Debugger->attach->Remote ARMLinux/Android debugger
4.5 選擇調(diào)試進程
4.6 Debugger option選項勾選,F(xiàn)9運行調(diào)試程序

4.7 等待調(diào)試jdb連接

如果提示無法附加到目標 VM,可以嘗試關閉掉Android studio,然后手動設置一下對應的端口進程。
$ adb shell ps | grep "包名"
$ adb -d forward tcp:8700 jdwp:進程號
4.8 下斷點

4.9 IDA動態(tài)調(diào)試
我們在j_AES_128_ECB_PKCS5Padding_Encrypt下個斷點,已知參數(shù)分別是要加密的字符串和秘鑰。運行程序至斷點位置,從R0寄存器可以看到就是我們要加密的字符串

而R1的值則是我們需要的秘鑰。

其他值也可以通過調(diào)試拿到。
三、驗證
拿到了我們需要的數(shù)據(jù)后,就可以開始簡單的驗證了。找一個在線加密的地址,用原始的字符串和key進行加密。

并將加密結果md5,得到“fde85ed3d5bce52db74cf300f9700504”。

對比一下抓包結果,加密值完全一致,說明沒有進行其他額外的加密了。

所以至此我們已經(jīng)知道了一切。
四、學習實踐總結
1、Charles抓包
HTTP/HTTPS抓包,高版本Android利用vpn轉發(fā)到代理,以解決不能抓HTTPS的問題
2、反編譯
關鍵代碼可以通過smali查看
3、插樁
通過修改smali文件,可以輸出指定的日志信息,增加彈窗Toast等等
4、Native Hook
Frida的使用,本次分析中,就用到了Frida來hook native函數(shù),觀察加密前后的結果。遇到難點是frida hook jstring類型的參數(shù)時,打印字符串的問題(已解決,類型轉換)。
5、so文件的分析
依然看不懂匯編代碼
6、移花接木
將目標的so文件,移植到自己的demo中,方便調(diào)試調(diào)用。
7、利用IDA動態(tài)調(diào)試so
成功拿到key,修改了校驗函數(shù)的返回值。