前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Crack App | yrx App 对抗赛第二、第三题加密签名对抗

Crack App | yrx App 对抗赛第二、第三题加密签名对抗

作者头像
咸鱼学Python
发布2022-06-24 14:31:38
4440
发布2022-06-24 14:31:38
举报
文章被收录于专栏:咸鱼学Python咸鱼学Python

图源:米游社

今日目标

昨天整了个珍惜逆向的团购,当了一晚上的客服,结果还是很多人错过拍大腿了,算了算了 还是老老实实写文章吧

aHR0cHM6Ly9hcHBtYXRjaC55dWFucmVueHVlLmNvbQ==

上一篇写了 yrx App 比赛的第一个题目

Crack App | yrx App 对抗赛第一题 Sign 算法的还原

今天搞一搞二、三题的加密签名,为什么把这两个放在一起写,是因为这两道题目有一个通用解法

Unidbg

即可以满足主办方的要求又可以完成 so 算法的脱机调用

第二题:so 层加密

抓包分析(第二题)

先来看看这第二题的请求包

time+app2两个请求包,主要看看app2

主要的参数很明显,还是sign

加密定位与分析(第二题)

根据上一篇文章

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

这个sign是下面的native方法

既然开始就决定要使用unidbg调用这个算法,那么就费劲拖到IDA里分析了

只需要用Frida确认sign的出入参数,之后方便使用Unidbg调用即可

使用下面的代码hook sign

代码语言:javascript
复制
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)

然后运行可以得到下面的打印结果

这里的str就是入参,可以知道就是page+:+time的组合

返回的结果看着很像Base64

先把出入参数复制保存起来,等最后和Unidbg 的结果做个对比

Unidbg 调用 so 算法(第二题)

之前写过一篇关于Unidbg环境搭建的教程,里面讲了如何下载开源项目并成功运行第一个demo

没有搭好环境的可以照着下面的链接先搭建一下

Crack App | 初试 Unidbg 环境搭建

这个appso命名很规范,所以不用看java层的加载代码也能很快的知道so是哪个

先把这个libmatch02.so复制出来

打开搭建好的unidbg项目,并创建一个app2的包,并将apkso都放进去

新建一个MainActivity.java文件,这个是我们调用so主逻辑的代码存放位置

如果之前没有写过的话,可以参考Unidbg自带的demo

下面直接附上主要的代码

代码语言:javascript
复制
public class MainActivity extends AbstractJni {
    private final AndroidEmulator emulator;
    private final VM vm;
    private final Memory memory;
    private final Module module;

    public MainActivity(){
        // 创建模拟器实例(这里必须是 64bit 的版本,因为是 64 位的 so)
        emulator = AndroidEmulatorBuilder
                .for64Bit()
                .build();
        // 获取内存
        memory = emulator.getMemory();
        // 设置解析器sdk版本
        memory.setLibraryResolver(new AndroidResolver(23));

        // 这里应该给一个 apk 的文件路径
     //vm = emulator.createDalvikVM();
        // 创建Android虚拟机,传入APK,Unidbg可以替我们做部分签名校验的工作
        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();
    // 调用JNI OnLoad,可以看到JNI中做的事情,比如动态注册以及签名校验等。
        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();
    }
}

这里面除了创建模拟器实例的时候需要用到的64bit之外,其他都是正常的逻辑

然后只要写一个方法调用sign就可以了

代码语言:javascript
复制
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运行结果如下

和我们 hook 的结果一样,之后只要搭配Unidbg Server就可以直接调用了


此为分割线


看过第二题的赶紧练起来,试试按照上面的思路把第三题做出来,做不出来再看下面的内容

说归说闹归闹,别拿点赞开玩笑,记得点赞


此为分割线


第三题:so 层加密带混淆

抓包分析(第三题)

第三题的抓包大同小异

也是time+app3两个请求包,主要看app3这个请求包

主要的分析参数是m

加密定位与分析(第三题)

根据上一篇文章

可以定位到下面的位置

然后和第二题一样,使用Frida确定出入参数就可以了,方便之后用Unidbg调用

第三题的crypt可以通过下面的代码hook

代码语言:javascript
复制
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结果如下

这个strpage+time*1000

timetime*1000

同样的先把出入参数复制保存起来,等最后和Unidbg 的结果做个对比

Unidbg 调用 so 算法(第三题)

看过第二题的小伙伴都知道前面的步骤了,这里直接跳过环境搭建等步骤

直接上代码

代码语言:javascript
复制
    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());
    }

逻辑的其他部分除了要替换apkso的路径之外,其他完全一样

以上就是yrx 的第二、第三题的题目讲解了,还好不限制Unidbg,不然连第二第三题就已经把我干掉了

End.

以上就是全部的内容了,咱们下次再会~

我是没有更新就在摸鱼的咸鱼

收到请回复~

我们下次再见。

对了,看完记得一键三连,这个对我真的很重要。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-05-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 咸鱼学Python 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 今日目标
  • 第二题:so 层加密
    • 抓包分析(第二题)
      • 加密定位与分析(第二题)
        • Unidbg 调用 so 算法(第二题)
        • 第三题:so 层加密带混淆
          • 抓包分析(第三题)
            • 加密定位与分析(第三题)
              • Unidbg 调用 so 算法(第三题)
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档