一、目標(biāo)
稼軒長短句有云:寶馬雕車香滿路。從此香車美女就成了標(biāo)配。這不李老板還沒聊幾個mm,又開始準(zhǔn)備換車了。
今天我們的目標(biāo)是 某汽車社區(qū)App v8.0.1。
二、步驟
脫個殼
李老板說這個App很拽,貌似是某個企業(yè)版的殼,連 Xcube都不好使,調(diào)試不了。
我們先不管他拽不拽,先用 BlackDex 把殼脫了先。
BlackDex提示脫殼成功,但是對應(yīng)的目錄下只有一個dex文件,明顯不對

還好我們有備用方案,據(jù)說 FDex2 脫殼也不錯,搞起來。
憂傷的是,F(xiàn)Dex2說不支持我的手機(jī)。 原因是我的系統(tǒng)版本太高 Android 10。
罷了,手機(jī)咱還是有好多部的。當(dāng)年找李老板申請從Android 4 - Android 10 都買了一部,測試用嘛。
先找了一臺Android 8.1 。正好這臺機(jī)器上也有 BlackDex。順手試試吧。

難道脫殼還和系統(tǒng)有關(guān)系? 正告各位兄弟: 高低版本的Android都備著,哪個能脫用哪個
抓個包

數(shù)了數(shù)signature,還是32位,這就尷尬了,難道還是MD5。
不管了,先搜搜哦

結(jié)果不多,這個 Map.put 太赤果果了,盤它。

感覺上應(yīng)該是這個sign了。
上Frida
var utilCls = Java.use("com.alibaba.sdk.android.oss.common.utils.OSSUtils");
utilCls.sign.implementation = function(a,b,c){
console.log(TAG + "a = " + a);
console.log(TAG + "b = " + b);
console.log(TAG + "c = " + c);
var rc = this.sign(a,b,c);
console.log(TAG + "sign = " + rc);
return rc;
}
跑起來。
TIP: 忘了插播一下,這個App沒有那么拽,手機(jī)里面跑葫蘆娃 hluda-server-15.xx,然后就可以跑起來。
憂傷的是,木反應(yīng)。 不科學(xué)呀。
仔細(xì)看看 Signature 和 signature 傻傻的分不清楚。居然犯這種低級錯誤。千萬不能讓李老板知道,不然快年底了,他肯定以這個為理由不給我加工資。

把忽略大小寫勾掉。再搜一遍,這次只有兩個結(jié)果了,但是這兩個結(jié)果看上去都不咋地。
這時需要祭出 找朋友 大法了。從同一個請求包里面另外找一個看上去比較稀有的參數(shù)來搜。這次我們看上了 nonce

這里看上去有戲。

進(jìn)去看看,我們看到了親愛的MD5。毫不猶豫的Hook之。
var utilsExCls = Java.use("com.aliyun.common.utils.MD5Util");
utilsExCls.getMD5.implementation = function(a){
console.log(TAG + "a = " + a);
var rc = this.getMD5(a);
console.log(TAG + "Md5 sign = " + rc);
return rc;
}
這次逮住了
Md5 sign = 35c40cb2b0fcf2a61ad316be7e912370
可以收工了。

返回?cái)?shù)據(jù)加解密

我們從抓包結(jié)果來看,請求包和結(jié)果里面都有一組 sd= 開頭的加密數(shù)據(jù)。 看上去像是詳情頁面的數(shù)據(jù)。
如何定位呢?我們先分析下特征,這組數(shù)據(jù)有三個特征:
1、sd= 開頭
2、數(shù)據(jù)都是大寫的M開頭
3、== 結(jié)尾,那大概率是Base64
先從Base64入手
var Base64Class = Java.use("android.util.Base64");
Base64Class.encodeToString.overload("[B", "int").implementation = function(a,b){
var rc = this.encodeToString(a,b);
console.log(">>> Base64 " + rc);
return rc;
}
跑起來,憂傷的是,木有結(jié)果。(可能是Base64在so層做或者干脆自己實(shí)現(xiàn)Base64算法)
那就換個方法,搜索 sd= 或者 "sd"
輕松定位到了 CheckCodeUtils 這個類
var CheckCodeUtils = Java.use("com.cloudy.lxxxlxxxbang.model.request.retrofit2.CheckCodeUtils");
var encrypt = CheckCodeUtils.encrypt.implementation = function (paramString, paramInt) {
console.log(TAG + 'aaa encrypt paramString:' + paramString);
console.log(TAG + 'aaa encrypt paramInt:' + paramInt);
var result = this.encrypt(paramString, paramInt);
console.log(TAG + 'aaa encrypt result:' + result);
return result;
}
var decrypt = CheckCodeUtils.decrypt.implementation = function (paramString) {
console.log(TAG + 'aaa decrypt paramString:' + paramString);
var result = this.decrypt(paramString);
console.log(TAG + 'aaa decrypt result:' + result);
return result;
}
完美,結(jié)果就不截圖了。
三、總結(jié)
關(guān)鍵字符串搜不到的時候,可以考慮考慮找找他們的朋友。
逆向分析是實(shí)踐課,沒有定法。不要糾結(jié)細(xì)枝末節(jié),也不要探究方法是否正統(tǒng)。能抓到老鼠就行。
預(yù)告一下,下節(jié)課咱們用 unidbg來跑這個算法。順便嘗試還原它 。

金屑雖貴,落眼成翳