当前位置: 首页 > news >正文

某短视频 sig3 逆向纯算分析

前言

今天来分析一下某短视频系列的 sig3 加密参数,主要目的是探索学习app接口的加解密机制。仅供学习,禁止用作其他用途。未经允许禁止任何形式的转载,保留追究法律责任的权利。

逻辑分析

app样本:5Zac55Wq5YWN6LS555+t5Ymn

一. unidbg运行

package com.xx;
import com.github.unidbg.AndroidEmulator;
import com.github.unidbg.Emulator;
import com.github.unidbg.Module;
import com.github.unidbg.arm.backend.Unicorn2Factory;
import com.github.unidbg.arm.context.RegisterContext;
import com.github.unidbg.debugger.BreakPointCallback;
import com.github.unidbg.debugger.Debugger;
import com.github.unidbg.file.FileResult;
import com.github.unidbg.file.IOResolver;
import com.github.unidbg.linux.android.AndroidEmulatorBuilder;
import com.github.unidbg.linux.android.AndroidResolver;
import com.github.unidbg.linux.android.dvm.*;
import com.github.unidbg.linux.android.dvm.array.ArrayObject;
import com.github.unidbg.linux.android.dvm.array.ByteArray;
import com.github.unidbg.linux.android.dvm.api.AssetManager;
import com.github.unidbg.linux.android.dvm.wrapper.DvmBoolean;
import com.github.unidbg.linux.android.dvm.wrapper.DvmInteger;
import com.github.unidbg.linux.file.SimpleFileIO;
import com.github.unidbg.memory.Memory;
import com.github.unidbg.pointer.UnidbgPointer;
import com.github.unidbg.virtualmodule.android.AndroidModule;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;import com.github.unidbg.virtualmodule.android.JniGraphics;public class sign extends AbstractJni implements IOResolver{@Overridepublic FileResult resolve(Emulator emulator, String pathname, int oflags) {return null;}private final AndroidEmulator emulator;private final VM vm;private final Module module;public sign() {// 创建模拟器实例,进程名建议依照实际进程名填写,可以规避针对进程名的校验emulator = AndroidEmulatorBuilder.for64Bit().addBackendFactory(new Unicorn2Factory(true)).setProcessName("com.xx")// 模拟手机文件的根路径.build();// 获取模拟器的内存操作接口final Memory memory = emulator.getMemory();// 设置系统类库解析memory.setLibraryResolver(new AndroidResolver(23));// 创建Android虚拟机,传入APK,Unidbg可以替我们做部分签名校验的工作vm = emulator.createDalvikVM(new File("xx"));// 如果提示缺失依赖sovm.setJni(this);new AndroidModule(emulator, vm).register(memory);new JniGraphics(emulator, vm).register(memory);emulator.getSyscallHandler().addIOResolver(this);   //重定向io// 设置是否打印Jni调用细节vm.setVerbose(true);DalvikModule dm1 = vm.loadLibrary("kwsgmain", true);module = dm1.getModule();dm1.callJNI_OnLoad(emulator);public static void main(String[] args) throws FileNotFoundException {sign test = new sign();AndroidEmulator emulator = test.emulator;VM vm = test.vm;test.call_doCommandNative_init();test.get_NS_sig3();}public String get_NS_sig3(){DvmClass dvmClass = vm.resolveClass("com.kuaishou.android.security.internal.dispatch.JNICLibrary");String methodSign="doCommandNative(I[Ljava/lang/Object;)Ljava/lang/Object;";DvmObject<?> context = vm.resolveClass("com.kwai.theater.KSApplication").newObject(null);String aa = "coder7777";DvmObject<?> ret1 = dvmClass.callStaticJniMethodObject(emulator, methodSign, 10418,new ArrayObject(new ArrayObject(new StringObject(vm, aa)),new StringObject(vm, "d74f8f6d-951f-4ba0-bace-e5666ea0e323"),DvmInteger.valueOf(vm, -1),DvmBoolean.valueOf(vm, false),context,null,DvmBoolean.valueOf(vm, false),new StringObject(vm, "")));System.out.println("QKING, initMain.ret-10418: " + ret1);return ret1.toString();}private void call_doCommandNative_init() {DvmClass dvmClass = vm.resolveClass("com.kuaishou.android.security.internal.dispatch.JNICLibrary");String methodSign="doCommandNative(I[Ljava/lang/Object;)Ljava/lang/Object;";DvmObject<?> context = vm.resolveClass("com.kwai.theater.KSApplication").newObject(null);  // DvmObject<?> ret11 = dvmClass.callStaticJniMethodObject(emulator, methodSign, 10412,new ArrayObject(null,new StringObject(vm, "d74f8f6d-951f-4ba0-bace-e5666ea0e323"),null,null,context,null,null));System.out.println("QKING, call_doCommandNative_init: " + ret11);}@Overridepublic void callStaticVoidMethodV(BaseVM vm, DvmClass dvmClass, String signature, VaList vaList) {switch (signature) {case "com/kuaishou/android/security/internal/common/ExceptionProxy->nativeReport(ILjava/lang/String;)V":return;}super.callStaticVoidMethodV(vm, dvmClass, signature, vaList);}@Overridepublic DvmObject<?> callObjectMethodV(BaseVM vm, DvmObject<?> dvmObject, String signature, VaList vaList) {switch (signature) {case "com/kwai/theater/KSApplication->getPackageCodePath()Ljava/lang/String;": {return new StringObject(vm, "/data/app/~~DsTsX9Czu7IXbyf7Kgqq9w==/com.kwai.theater-Vd-G-su_DD7b_HtgBaAt5w==/base.apk");}case "com/kwai/theater/KSApplication->getPackageName()Ljava/lang/String;": {return new StringObject(vm, "com.kwai.theater");}case "com/kwai/theater/KSApplication->getAssets()Landroid/content/res/AssetManager;": {return new AssetManager(vm, signature);}case "com/kwai/theater/KSApplication->getPackageManager()Landroid/content/pm/PackageManager;": {return vm.resolveClass("android/content/pm/PackageManager").newObject(signature);}}return super.callObjectMethodV(vm, dvmObject, signature, vaList);}@Overridepublic DvmObject<?> callStaticObjectMethodV(BaseVM vm, DvmClass dvmClass, String signature, VaList vaList) {switch (signature) {case "com/kuaishou/android/security/internal/common/ExceptionProxy->getProcessName(Landroid/content/Context;)Ljava/lang/String;":return new StringObject(vm, "com.kwai.theater");case "com/kuaishou/android/security/internal/common/ExceptionProxy->getThreadByName(Ljava/lang/String;)Ljava/lang/String;":String threadName = String.valueOf(vaList.getIntArg(0));return new StringObject(vm, threadName);}return super.callStaticObjectMethodV(vm, dvmClass, signature, vaList);}
  1. 正常出结果,这块就没什么好讲的了,网上有很多份,唯一要注意的就是要先初始化一下
    在这里插入图片描述

  2. 出结果后,固定入参 ”coder7777“,结果每次都不一样,猜测是有时间戳或者随机数,我们来测试一下,首先固定时间戳:
    在这里插入图片描述
    此时发现入参固定,时间戳固定,结果一致,结果为42530000d2f6651b0a0a09085baf1cd100b40776171b1503,更改参数和时间戳也看不出什么了,咱们接着往下走。

  3. so去花
    跟着大佬学习肯定不会错,我这里也是看着龙哥的文章去的花,具体过程就不分析了,文章里面或者其他资料都很多,跟着照做就可以实现了。

https://www.yuque.com/lilac-2hqvv/zfho3g/issny5?#%20%E3%80%8A%E8%8A%B1%E6%8C%87%E4%BB%A4%E5%A4%84%E7%90%86%EF%BC%88%E4%B8%80%EF%BC%89%E3%80%8B

二. trace分析

        try {emulator.traceCode(module.base, module.base + module.size).setRedirect(new PrintStream(filePath +"traceCodeCar_0x20694.log"));}catch (IOException e) {throw new IllegalStateException(e);}
  1. 先trace一份代码出来,首先 根据结果”42530000d2f6651b0a0a09085baf1cd100b40776171b1503“查找,看看是哪里生成的,咱们在trace里面搜索一下 0x1b(不要搜索0x03这些结果比较多)。搜索发现这里会比较像:
    在这里插入图片描述
    unidbg在这里断一下,看看x21
    在这里插入图片描述
    看样子结果是我们想要的,然后打开ida看下流程,快捷键”x“和打断点配合,最终确认如下
    在这里插入图片描述
    上面就是v460 生成的地方,我们在这个地方打上断点:
    在这里插入图片描述
    我们python实现一下异或操作 注意共执行23轮,然后第二十四位不变:
    在这里插入图片描述
    也没问题,结果正是 42530000d2f6651b0a0a09085baf1cd100b40776171b1503

  2. 现在我们就要分析 41510100d5f0601f0100000054a111dd13a61666000d0003 的来源了,这里我们先测试下
    只修改明文:

 41510100d5f0601f0100000054a111dd13a61666000d0003  原文41510100d5f0601f0100000061193a8d13a61666000d00a5 修改后

13-16位和最后一位变化

只修改时间戳:

  41510100d5f0601f0100000054a111dd13a61666000d0003  原文415101000e9525310100000054a111dd12a61666000d004f 修改后

5-8处字节发生变化 17-19和最后一个字节发生变化。

两者均修改

 41510100d5f0601f0100000054a111dd13a61666000d0003  原文415101000e9525310100000061193a8d12a61666000d00f1 修改后

5-8处字节发生变化,13~20处字节发生变化,和最后一个字节变化

三.明文分析

                                       crc32算法
  1. 由以上可知,13-16位和明文”coder7777“有关,13-16位是 dd11a154, 咱们trace里面搜索一下:在这里插入图片描述在0x1620处,我们在这里打个断点:
    在这里插入图片描述
    mx0是密文,mx1=0x30是长度,根据网上资料可以,这里用的是crc32算法,我们来测试一下:
    在这里插入图片描述
    得到结果 ”dd11a154’ 且没有魔改

    									aes-cbc加密
    

这里再看下“b7332938d71fbd84260aabaf3ecd0e6e164c729106057925b51710d697f5e06ced13be5d336bf29ad77fbad8cb814cad”是怎么来的。还是根据网上资料,初步认为是aes-cbc,咱们只需要验证是不是即可。
上文的b73329xxxxx所在的位置是 0x404e44c0,咱们这里trace追踪一下

 emulator.traceWrite(0x404e44c0,0x404e44c0+0x30);

在这里插入图片描述
这里看到调用的地方是在ilbc里面,0x1d62c是结束调用的地方,咱们在 0x1d62c 前面的位置打个断点
在这里插入图片描述
可以看到是在 0x404d31b0 这个位置,我们在trace一下:

emulator.traceWrite(0x404d31b0,0x404d31b0+0x30);

在这里插入图片描述
可以看到是在0x25b30,ida分析一下,这里大概就是aes算法的地方了,再具体的就没必要去分析了,网上的资料很多,例如如何知道是aes,且是cbc模式,这里就不细说了。
咱们hook一下入参:
在这里插入图片描述

这里一直入参为 33c4d4f0f3316a554af23888c78af4b44050d6c952572c743e047af26c1d8c3e
结果为 b7332938d71fbd84260aabaf3ecd0e6e164c729106057925b51710d697f5e06ced13be5d336bf29ad77fbad8cb814cad
加密方式为 aes-cbc.
咱们直接上dfa:

        debugger.addBreakPoint(1073741824 + 0x24B1C, new BreakPointCallback() {int count = 1;int count2 = 0;@Overridepublic boolean onHit(Emulator<?> emulator, long address) {byte[] data= {0x1};if (count % 9 == 0) {data[0] = (byte) randint(0,0xff);emulator.getBackend().mem_write(0x404d3150 + count2 * 0x10 + randint(0, 15), data);}count++;if (count == 11) {count = 1;count2++;}return true;}});

运行10次以上,得到一个原文和多个错误密文,然后使用phoenixAES算出第10轮秘钥
在这里插入图片描述
算出后再用 Stark 算出主密钥
在这里插入图片描述
这里算出密钥后,验证一下:
在这里插入图片描述
结果正确,说明咱们aes密钥找对了

										hmac-sha256		

最后一步了,找出 33c4d4f0f3316a554af23888c78af4b44050d6c952572c743e047af26c1d8c3e 生成的位置,由hook入参可知,33c4xxx存在 0x404d8340,咱们trace一下

emulator.traceWrite(0x404d8340,0x404d8340+0x20);

在这里插入图片描述
是在0x1ce50,此时已经生成结果,对上一个函数进行hook
在这里插入图片描述
在这里插入图片描述
hmac的特征值就是0x36和0x5c,经过验证
在这里插入图片描述
所以这个就是密钥,python验证一下
在这里插入图片描述
ok,这里也没问题,至此明文分析介绍

四.时间戳分析

这个就比较简单了,网上也有很多说明,就是时间戳的16进制,验证一下
在这里插入图片描述
也没问题,然后5-8字节发生的变化,这个是随机数,使用了时间戳作为种子的随机数,这里就不多分析了,知道结果即可。

五.最后一位分析

前面所有字节均已分析完毕,还有最后一位,回到咱们最开始分析的地方

 v370 = 0LL;DWORD1(v460[1]) = (qword_644D0 >> 57) & 2 | ((qword_644D0 & 0x2000000000000000LL) != 0) | (qword_644D0 >> 58) & 4 | (qword_644D0 >> 53) & 0x10 | (qword_644D0 >> 54) & 0x20 | (qword_644D0 >> 44) & 0x40 | 0xD00 | (v368 << 24);do{*(v460 + v370) ^= v368 ^ v370;++v370;}

这里循环了23轮,异或得到最终结果。我们在这里hook一下,并根据代码分析发现
在这里插入图片描述
最后一位就是(qword_644D0 >> 57) & 2 | ((qword_644D0 & 0x2000000000000000LL) != 0) | (qword_644D0 >> 58) & 4 | (qword_644D0 >> 53) & 0x10 | (qword_644D0 >> 54) & 0x20 | (qword_644D0 >> 44) & 0x40 | 0xD00 | (v368 << 24)计算得到的,python验证一下
在这里插入图片描述
至此,所以数据均已分析完成

总结

1.前四位固定值
2.5-8处字节又时间戳为种子的随机数生成
3.9-12固定值
4.13-16由明文生成,采用 CRC32 + AES-CBC + HMAC-SHA256 生成
5.17-20 时间戳生成
6.21-23 固定值
6.第24位由前23位求和取反算出
7.前六步生成的20位密文异或得到最终加密参数

http://www.dtcms.com/a/428089.html

相关文章:

  • CMSIS设计的理解
  • 串扰06-近端串扰的大小
  • 哪些网站是做食品网站前台设计方案
  • 达州市网站建设wordpress文章与页面
  • Powershell维护系统管理任务(五)
  • 美团滑块-[behavior] 加密分析
  • 泉州专业建站单位网站建设实施方案
  • 动作捕捉技术与服务 | 推动人形机器人实现规模化高质量数据采集与训练
  • 网站开发软件有哪设计师网络叫法
  • 服务类网站开发中山家居企业网站建设
  • 【Android】Kotlin.flow在主线程collect为什么不阻塞主线程?
  • 数据整合展示中心
  • 阜宁网站制作哪家好我公司想做网站
  • Spring IOC源码篇七 核心方法obtainFreshBeanFactory自定义标签
  • 在哪里找做网站的客户郴州网络营销
  • 产生式规则对人工智能中自然语言处理深层语义分析的影响与启示研究
  • 南宁专业网站开发潍坊市网站制作
  • 网站后台登录密码修改自己网站做问卷调查
  • 在命令提示符页面中用pip命令行安装Python第三方库的详细步骤
  • 杭州开发网站的公司网站默认中文字体
  • 深度解析Epoch:模型训练中的“时间与泛化“博弈
  • MySQL索引特性(重点)
  • 【有序数组去重】2022-11-25
  • 【11408学习记录】考研数学线性代数精讲:矩阵方程求解与秩的深度解析
  • 专业沈阳网站制作大数据公司排名
  • 做受视频网站现在流行什么语言建设网站
  • TDengine 时序函数 STATEDURATION 用户手册
  • Java-Spring入门指南(十二)SpringAop的三种实现方式
  • 网站在线统计代码cms开发框架
  • CometD 长轮询协议及在Salesforce中的应用