某酒店App sign、appcode簽名解析(一) 帶殼分析 r0tracer

1、目標

main.png

今天的目標是這個sign和appcodejava

2、步驟

Jadx無法上了

app加了某梆的企業版,Jadx表示無能爲力了。android

FRIDA-DEXDump

DexDump出來,木有找到有效的信息。git

Wallbreaker

葫蘆娃的Wallbreaker能夠作些帶殼分析,不過這個樣本,用Frida的Spawn模式能夠載入,Attach模式會失敗。而直接用Objection確沒法載入。致使用不了Wallbreaker。github

r0tracer

今天的新朋友是肉絲大佬的 r0tracer正則表達式

github.com/r0ysue/r0tr…安全

r0tracer能夠根據黑白名單批量追蹤類的全部方法。 咱們來嘗試追蹤一下包含 sign 的類或者方法微信

function main() {
    Java.perform(function () {
        console.Purple("r0tracer begin ... !")
        /*
        //如下三種模式,取消註釋某一行以開啓
        */
        //A. 簡易trace單個函數
        // traceClass("javax.crypto.Cipher")
        //B. 黑白名單trace多個函數,第一個參數是白名單(包含關鍵字),第二個參數是黑名單(不包含的關鍵字)
        // hook("javax.crypto.Cipher", "$");
		hook("sign", "$");
        //C. 報某個類找不到時,將某個類名填寫到第三個參數,好比找不到com.roysue.check類。(前兩個參數依舊是黑白名單)
        // hook("com.roysue.check"," ","com.roysue.check");
    })
}
複製代碼

Spawn模式啓動Appmarkdown

$ frida -U -f com.platexx.boxxoota -l r0tracer.js  --no-pause -o saveLog1.txt
複製代碼

輸出app

Spawned `com.platexx.boxxoota`. Resuming main thread!                   
[MI NOTE Pro::com.platexx.boxxoota]-> r0tracer begin ... !
start
Begin Search Class...
Found Class => 
Tracing Method : com.wxxotel.app.service.signservice.OpenSignService.execute [1 overload(s)]
Tracing Method : com.wxxotel.app.service.signservice.OpenSignService.getPath [1 overload(s)]
Tracing Method : com.wxxotel.app.service.signservice.OpenSignService.$init [1 overload(s)]
複製代碼

木有啥有用的信息,我們換個 試試 Sign函數

輸出,而後,而後就掛了……

Spawned `com.platexx.boxxoota`. Resuming main thread!                   
[MI NOTE Pro::com.platexx.boxxoota]-> r0tracer begin ... !
start
Begin Search Class...
Found Class => 
Tracing Method : libcore.reflect.GenericSignatureParser.isStopSymbol [1 overload(s)]
Tracing Method : libcore.reflect.GenericSignatureParser.expect [1 overload(s)]
Tracing Method : libcore.reflect.GenericSignatureParser.parseClassSignature [1 overload(s)]
Tracing Method : libcore.reflect.GenericSignatureParser.parseClassTypeSignature [1 overload(s)]
Tracing Method : libcore.reflect.GenericSignatureParser.parseFieldTypeSignature [1 overload(s)]
Tracing Method : libcore.reflect.GenericSignatureParser.parseForClass [1 overload(s)]
複製代碼

這個 libcore.XXXX類,一看就不像是我們的菜,過濾掉它再試試。

hook("Sign", "libcore");
複製代碼

啊哈,這下看上去很拉風的樣,貌似有戲。

翻了翻輸出,

com.besxxxhotel.app.whnetcomponent.utils.SignUtil.getAppCode [1 overload(s)]
com.besxxxhotel.app.whnetcomponent.utils.SignUtil.getSignString [1 overload(s)]
複製代碼

這兩兄弟至關可疑,咱們此次追蹤下 SignUtil

hook("SignUtil", "$");
複製代碼
*** entered com.platexx.boxxoota.app.whnetcomponent.utils.SignUtil.getSignString
arg[0]: 0 => "0"
arg[1]: vadjlr4k3o;qj4io23ug9034uji5rjn34io5u83490u5903huq => "vadjlr4k3o;qj4io23ug9034uji5rjn34io5u83490u5903huq"
arg[2]: 00000000-7e21-1806-0000-00000033c587 => "00000000-7e21-1806-0000-00000033c587"
arg[3]: 1622430128929 => "1622430128929"
arg[4]: 0,0 => "0,0"
arg[5]: 6698 => "6698"
java.lang.Throwable
	at com.besxxxhotel.app.whnetcomponent.utils.SignUtil.getSignString(Native Method)
	at com.besxxxhotel.app.whnetcomponent.net.JJSignInterceptor.handlerRequest(JJSignInterceptor.java:114)
	at com.besxxxhotel.app.whnetcomponent.net.JJSignInterceptor.intercept(JJSignInterceptor.java:38)
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
	at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
	at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:200)
	at okhttp3.RealCall$AsyncCall.execute(RealCall.java:147)
	at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
	at java.lang.Thread.run(Thread.java:760)

========================================================================================================================================================================================================
retval: C5F29B0EF472EDA271313155307E8077 => "C5F29B0EF472EDA271313155307E8077"
*** exiting com.besxxxhotel.app.whnetcomponent.utils.SignUtil.getSignString
複製代碼
  • 參數 0 1 是固定值
  • 參數 2 應該是 did
  • 參數 3 是當前時間戳
  • 參數 4 也是固定值
  • 參數 5 就比較奇怪了, 在日誌裏面搜索一下,發現 5是 函數 decodeASCII 的返回值, 它的入參是一個 java.util.Map。

在117行微調一下,打印下這個map

var strType = JSON.stringify(arguments[j]);
// console.log(strType);
			
if(strType.indexOf('HashMap') > 0){
	console.log(arguments[j].entrySet().toArray());
}
複製代碼

就知道是本次請求的內容。

systemVersion=7.0,sid=306267,userId=0,clientVersion=5.2.9,deviceType=MI NOTE Pro,did=174670d6754469115964f1387aed0a96,appId=105,deviceCode=,os=android
複製代碼

搞定,收工……

3、總結

趁手的工具多搞幾個,技多不壓身。

r0tracer的名稱過濾,搞成正則表達式會不會更帥?

殼仍是要搞一下的,若是把殼脫了,這個App就沒啥難度了。

ffshow.jpeg

當你走上了不同的道路,你纔有可能看到和別人不同的風景

TIP: 本文的目的只有一個就是學習更多的逆向技巧和思路,若是有人利用本文技術去進行非法商業獲取利益帶來的法律責任都是操做者本身承擔,和本文以及做者不要緊,本文涉及到的代碼項目能夠去 奮飛的朋友們 知識星球自取,歡迎加入知識星球一塊兒學習探討技術。有問題能夠加我wx: fenfei331 討論下。

關注微信公衆號: 奮飛安全,最新技術乾貨實時推送

相關文章
相關標籤/搜索