Crack App | yrx App 對(duì)抗賽第二、第三題加密簽名對(duì)抗
第一時(shí)間關(guān)注Python技術(shù)干貨!

圖源:米游社
今日目標(biāo)
昨天整了個(gè)珍惜逆向的團(tuán)購,當(dāng)了一晚上的客服,結(jié)果還是很多人錯(cuò)過拍大腿了
,算了算了? 還是老老實(shí)實(shí)寫文章吧
aHR0cHM6Ly9hcHBtYXRjaC55dWFucmVueHVlLmNvbQ==
上一篇寫了 yrx App 比賽的第一個(gè)題目
Crack App | yrx App 對(duì)抗賽第一題 Sign 算法的還原
今天搞一搞二、三題的加密簽名,為什么把這兩個(gè)放在一起寫,是因?yàn)檫@兩道題目有一個(gè)通用解法
Unidbg
即可以滿足主辦方的要求又可以完成 so 算法的脫機(jī)調(diào)用
第二題:so 層加密
抓包分析(第二題)
先來看看這第二題的請(qǐng)求包
time+app2兩個(gè)請(qǐng)求包,主要看看app2

主要的參數(shù)很明顯,還是sign
加密定位與分析(第二題)
根據(jù)上一篇文章

可以快速定位加密位置如下

這個(gè)sign是下面的native方法

既然開始就決定要使用unidbg調(diào)用這個(gè)算法,那么就費(fèi)勁拖到IDA里分析了
只需要用Frida確認(rèn)sign的出入?yún)?shù),之后方便使用Unidbg調(diào)用即可
使用下面的代碼hook sign
console.log("腳本加載成功");
function?main(){
????Java.perform(function()?{
????????var?clazz?=?Java.use('com.yuanrenxue.match2022.fragment.challenge.ChallengeTwoFragment');
????????clazz.sign.implementation?=?function(str)?{
????????????console.log('find?======');
????????????console.log('str?========>'?+?str)
????????????var?result?=?this.sign(str)
????????????console.log("result?=======>"?+?result)
????????????return?result;
????????}
????});
}
setImmediate(main)
然后運(yùn)行可以得到下面的打印結(jié)果

這里的str就是入?yún)ⅲ梢灾谰褪?code style="font-size: 14px;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(71, 193, 168);">page+:+time的組合
返回的結(jié)果看著很像Base64
先把出入?yún)?shù)復(fù)制保存起來,等最后和Unidbg 的結(jié)果做個(gè)對(duì)比
Unidbg 調(diào)用 so 算法(第二題)
之前寫過一篇關(guān)于Unidbg環(huán)境搭建的教程,里面講了如何下載開源項(xiàng)目并成功運(yùn)行第一個(gè)demo
沒有搭好環(huán)境的可以照著下面的鏈接先搭建一下
Crack App | 初試 Unidbg 環(huán)境搭建
這個(gè)app的so命名很規(guī)范,所以不用看java層的加載代碼也能很快的知道so是哪個(gè)

先把這個(gè)libmatch02.so復(fù)制出來
打開搭建好的unidbg項(xiàng)目,并創(chuàng)建一個(gè)app2的包,并將apk和so都放進(jìn)去

新建一個(gè)MainActivity.java文件,這個(gè)是我們調(diào)用so主邏輯的代碼存放位置
如果之前沒有寫過的話,可以參考Unidbg自帶的demo
下面直接附上主要的代碼
public?class?MainActivity?extends?AbstractJni?{
????private?final?AndroidEmulator?emulator;
????private?final?VM?vm;
????private?final?Memory?memory;
????private?final?Module?module;
????public?MainActivity(){
????????//?創(chuàng)建模擬器實(shí)例(這里必須是?64bit?的版本,因?yàn)槭?64?位的?so)
????????emulator?=?AndroidEmulatorBuilder
????????????????.for64Bit()
????????????????.build();
????????//?獲取內(nèi)存
????????memory?=?emulator.getMemory();
????????//?設(shè)置解析器sdk版本
????????memory.setLibraryResolver(new?AndroidResolver(23));
????????//?這里應(yīng)該給一個(gè)?apk?的文件路徑
?????//vm?=?emulator.createDalvikVM();
????????//?創(chuàng)建Android虛擬機(jī),傳入APK,Unidbg可以替我們做部分簽名校驗(yàn)的工作
????????vm?=?emulator.createDalvikVM(new?File("unidbg-android/src/test/java/com/app2/app-match-22.apk"));
????????//?打印日志
????????vm.setVerbose(true);
????????vm.setJni(this);
?????//?加載?so?
????????DalvikModule?dalvikModule?=?vm.loadLibrary(new?File("unidbg-android/src/test/java/com/app2/libmatch02.so"),?false);
????????//?獲取本SO模塊的句柄
????????module?=?dalvikModule.getModule();
????//?調(diào)用JNI OnLoad,可以看到JNI中做的事情,比如動(dòng)態(tài)注冊(cè)以及簽名校驗(yàn)等。
????????vm.callJNI_OnLoad(emulator,module);
????}
????public?static?void?main(String[]?args)?{
????????long?start?=?System.currentTimeMillis();
????????MainActivity?mainActivity?=?new?MainActivity();
????????System.out.println("load?the?vm?"+(?System.currentTimeMillis()?-?start?)+?"ms");
????????mainActivity.getHash();
????}
}
這里面除了創(chuàng)建模擬器實(shí)例的時(shí)候需要用到的64bit之外,其他都是正常的邏輯
然后只要寫一個(gè)方法調(diào)用sign就可以了
private?void?getHash()?{
????????DvmObject>?dvmObject?=?vm.resolveClass("com/yuanrenxue/match2022/fragment/challenge/ChallengeTwoFragment").newObject(null);
????????String?input?=?"3:1652458832";
????????DvmObject>?ret?=?dvmObject.callJniMethodObject(emulator,?"sign(Ljava/long/String;)Ljava/long/String;",?input);
????????System.out.println("result?==>"?+?ret.getValue());
????}
Unidbg運(yùn)行結(jié)果如下

和我們 hook 的結(jié)果一樣,之后只要搭配Unidbg Server就可以直接調(diào)用了
此為分割線
看過第二題的趕緊練起來,試試按照上面的思路把第三題做出來,做不出來再看下面的內(nèi)容
說歸說鬧歸鬧,別拿點(diǎn)贊開玩笑,記得點(diǎn)贊
此為分割線
第三題:so 層加密帶混淆
抓包分析(第三題)
第三題的抓包大同小異

也是time+app3兩個(gè)請(qǐng)求包,主要看app3這個(gè)請(qǐng)求包

主要的分析參數(shù)是m
加密定位與分析(第三題)
根據(jù)上一篇文章

可以定位到下面的位置

然后和第二題一樣,使用Frida確定出入?yún)?shù)就可以了,方便之后用Unidbg調(diào)用
第三題的crypt可以通過下面的代碼hook
console.log("腳本加載成功");
function?main(){
????Java.perform(function()?{
????????var?clazz?=?Java.use('com.yuanrenxue.match2022.fragment.challenge.ChallengeThreeFragment');
????????clazz.crypto.overload('java.lang.String',?'long').implementation?=?function(str,time)?{
????????????console.log('find?======>?crypt');
????????????console.log("str?===>???"+str)
????????????console.log("time?===>???"+time)
????????????var?result?=?this.crypto(str,time)
????????????console.log("result?====>???"?+?result)
????????????return?result;
????????}
????});
}
setImmediate(main)
hook結(jié)果如下

這個(gè)str是page+time*1000
time是time*1000
同樣的先把出入?yún)?shù)復(fù)制保存起來,等最后和Unidbg 的結(jié)果做個(gè)對(duì)比
Unidbg 調(diào)用 so 算法(第三題)
看過第二題的小伙伴都知道前面的步驟了,這里直接跳過環(huán)境搭建等步驟
直接上代碼
????private?void?getHash()?{
????????DvmObject>?dvmObject?=?vm.resolveClass("com/yuanrenxue/match2022/fragment/challenge/ChallengeThreeFragment").newObject(null);
????????String?input?=?"懶得敲了";
????????Long?time?=?懶得敲了;
????????DvmObject>?ret?=?dvmObject.callJniMethodObject(emulator,?"crypto(Ljava/lang/String;J)Ljava/lang/String;",?input,time);
????????System.out.println("result?==>"?+?ret.getValue());
????}
邏輯的其他部分除了要替換apk和so的路徑之外,其他完全一樣
以上就是yrx 的第二、第三題的題目講解了,還好不限制Unidbg,不然連第二第三題就已經(jīng)把我干掉了
End.
以上就是全部的內(nèi)容了,咱們下次再會(huì)~
公眾號(hào)配套技術(shù)交流群,備注【咸魚666】,入群交流
我是沒有更新就在摸魚的咸魚
收到請(qǐng)回復(fù)~
我們下次再見。
對(duì)了,看完記得一鍵三連,這個(gè)對(duì)我真的很重要。
