关于安全:某酒店App-signappcode签名解析一-带壳分析-r0tracer

57次阅读

共计 4181 个字符,预计需要花费 11 分钟才能阅读完成。

一、指标

明天的指标是这个 sign 和 appcode

二、步骤

Jadx 没法上了

app 加了某梆的企业版,Jadx 示意无能为力了。

FRIDA-DEXDump

DexDump 进去,木有找到无效的信息。

Wallbreaker

葫芦娃的 Wallbreaker 能够做些带壳剖析,不过这个样本,用 Frida 的 Spawn 模式能够载入,Attach 模式会失败。而间接用 Objection 确无奈载入。导致用不了 Wallbreaker。

r0tracer

明天的新敌人是肉丝大佬的 r0tracer

https://github.com/r0ysue/r0tracer

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 模式启动 App

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

输入

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

搞定,出工……

三、总结

趁手的工具多搞几个,技多不压身。

r0tracer 的名称过滤,搞成正则表达式会不会更帅?

壳还是要搞一下的,如果把壳脱了,这个 App 就没啥难度了。

当你走上了不一样的路线,你才有可能看到和他人不一样的风光

正文完
 0