首页
社区
课程
招聘
[原创]记录一次对tt算法的分析
发表于: 4天前 2483

[原创]记录一次对tt算法的分析

4天前
2483

记录一次对tt算法的分析

引子

最近在研究TT的六神算法,目前完成度大概在70%到80%之间吧。六神中的五个部分都相对简单,但Medusa这部分很复杂。其构成大致如下:

  • +0x00:时间戳与某个常量异或。
  • +0x20:随机数的低两位。
  • +0x22:固定的 0 和 1。
  • +0x24:魔改AES结果的最后一字节。
  • +0x25:加密的 Protobuf 数据。
  • 最后两字节:随机数的高两位。

在上述参数中,最复杂、最折腾人的就是那段加密的Protobuf数据,共有几十个字段,且大部分都是在进程刚启动时进行初始化。从分析来看,这部分数据应该是用于收集系统环境信息,解密后的内容如下:

本文的目标是分析16号字段中'A3xcV-ObJSg3dWOrqH5y6AjA3'字符串的来源。经观察,该字符串在进程启动时保持不变,但在运行几分钟后可能会发生变化。先来看下该固定字符串的生成方式。

字符串在哪里被初始化

逆推trace日志,发现该值存储在一个复杂的数据结构中, 而且这个复杂的数据结构是一个全局变量。

查找这个全局变量的交叉引用,发现可能在+0x475c0处进行了初始化。

所以我们将上述trace日志转为Frida代码来hook确认一下。

从错误日志中能看出,并没有在这里初始化。而且这个库被混淆的特别厉害,所以现在最好的办法就是上调试器下内存写断点。
为了调试方便,将Frida代码再转为GDB脚本,作用是从全局变量中读取出目标字符串。

再写一个脚本,当指定的库刚被加载时就立马断下。

在+0x47608处下断点,命中后打印字符串,根据输出日志在0x7e3ff24b58处下内存写入断点。

命中后再次打印,根据输出日志继续下内存写断点。

如此循环操作几次后,发现大概是在+0x127AC8附近进行初始化。

在+0x127AC8处hook,发现被大量调用,这说明现在是在一个通用函数中,并不是真正进行初始化的地方。

对于这种情况最好的办法就是通过栈回溯来找到关键点,但Frida自带的栈回溯功能有些鸡肋,所以还需要自己想想办法。通过静态观察,发现绝大部分函数都比较标准,在函数头有以下特征:

  1. 将老FP和LR寄存器一起保存到栈上。
  2. FP寄存器是栈基。
  3. 当前FP指向老FP。

    用图来表示更清晰。

    基于上述分析,可根据下面这个公式进行递归回溯。
    PREV_LR = *(CURRENT_FP + 0x8)
    PREV_FP = *(CURRENT_FP)
    PREV_PREV_LR = *(PREV_FP + 0x8)
    ....
    回溯的结果如下,+0x123cc4是最后一个有效的地址。

    该地址处是一个JNI接口,被大量调用,根据调用参数的不同来调用不同的处理函数,所以肯定不是我们要找的关键点。

    接下来分析倒数第二个栈回溯地址(+0x541d8)。经过验证,该地址仅被执行过一次,因此可以确定它是一个关键点。

字符串的由来

+0x541d8地址所在的函数位于+0x54170处,函数比较复杂,所以我们直接trace。使用Frida hook +0x54170函数,当命中时保存上下文环境并进行trace。

trace完了共一百多万行,先定位到上述的hook点+0x127AC8处,并根据如下代码反推。

最终成功定位到字符串赋值的起始位置,似乎是通过不同的索引查询同一张表得到的。因此,关键点主要集中在两个方面:第一,这张表是如何生成的;第二,这些索引是如何来的。

先来看0x7b9c84ae00这张表,它来自于堆上,大小0xab10。

因此,可以利用这个正则7b9c8[4|5][0-9a-zA-Z]{4}\[在trace日志中查找对表赋值的地方。经一番查找,发现了一处特征代码。

该代码循环读取0x7e46d92940常量数组中的值作为索引,对一个值取低3位,然后将值存储到表中。0x7e46d92940常量数组如下:

通过对常量数组和算法的特征,能确定这就是Inflate解压算法中用于构建哈夫曼树的部分,其源码如下:

现在既然已经确定了是解压算法,那么只需要找到算法的输入数据就行了。根据对源码的分析,tinf_getbits函数中引用了输入参数,函数逻辑如下:
num固定为3

d->source中存储的就是输入参数。

这段代码在trace日志中表现如下,对照源码来看,x25中的地址0x7b9a63e6ca就是原始输入参数。

0x7b9a63e6ca的起始地址是0x7b9a63e6c0,被赋值如下:

其中,前4个字节暂不清楚作用,从第4个字节开始就能看到zlib的魔法头0x78 0x1。解压就可以看到是一个json数据,其中包含了目标字符串。

OK,那么现在就应该去分析0x7b9a63e6c0中的数据从何而来。0x7b9a63e6c0的生成算法如下,一眼看出是rc4:
异或,模256,状态交换

初始化s盒

KSA

确定了RSA算法后,只需要找到输入数据和密钥即可。在RC4算法中KSA部分引用密钥,异或部分引用原始数据,因此可以得出0x7bfb738800中存储的是密钥,0x7f0d010600中存储的是原始数据。将原始数据和密钥从trace中读出来,用python来验证,确定是标准的rc4算法。

先来看0x7f0d010600中的原始数据,来自0x7b9c8d1b80,大小0x11c。

0x7b9c8d1b80来自0x7bb39d9400。

0x7bb39d9400来自7bb3daa000。

7bb3daa000来自系统调用,调用号0x3f。

不同的内核版本其调用号也不相同,在我的设备上0x3f调用号对应的系统调用是read。

很明显,这段输入数据应该是通过读取文件而来。read函数的第一个参数是文件句柄,在trace日志中的值为0x1ec,它来自于openat系统调用。

openat系统调用第二个参数是文件路径,这里就不继续分析了,直接hook打印参数,发现确实打开的是本地文件,该文件中的内容被rc4加密了。

再来分析0x7bfb738800中的密钥。0x7bfb738800中的值来自to hex string算法,原始hex数据为0x7b40e71840。

0x7b40e71840中的值来自0x7e7dec42e8,大小0x10字节。

0x7e7dec42e8来自0x7e7dec41f8。

0x7e7dec41f8来自MD5算法,从下面的常量和算法特征中能一眼看出。

在MD5算法中,会在原始数据的末尾先填充一个0x80,再填充0x0,直到补齐56字节,最后再填充8字节长度(位数)。所以根据这个特征,只要在trace日志中找到填充的地方,就能找到原始数据。

trace中填充的地方如下,因此能得到原始数据的长度为0x14(0xa0 / 8),原始数据存储在0x7e7dec4208中。

0x7e7dec4208来自0x7b9aadada0。

0x7b9aadada0来自0x7e7dec42e0。

0x7e7dec42e0来自0x7e7dec4220。

0x7e7dec4220来自sha1算法,从下面这些常量和右旋操作能看出。

同理,也可以根据sha1的填充逻辑来确定原始数据。sha1的填充逻辑与MD5基本相同,区别在于最后填充的8字节长度在MD5中是以小端形式存储,在sha1中是以大端。所以基于这个逻辑,可以得出原始数据为32765f696473,长度为6(0x30 / 8)。32765f696473是一个字符串,以大端格式读取为“sdi_v2”。

总结

经过上述分析,可以确定目标字符串来源于一段 JSON 数据,而这段 JSON 数据来自于一个经过加密的本地文件。该文件采用RC4算法进行加密,其密钥生成过程如下:

  1. 对字符串 "sdi_v2" 进行 SHA-1 计算,得到 20 字节的结果;
  2. 将第一步得到的数据进行MD5计算,生成16字节的结果;
  3. 将第二步的结果转换为十六进制字符串,从而得到 32 字节的密钥。

写这种算法分析的帖子真的是太无聊了,就先分析到这里吧,后续有机会再来谈下被加密的本地文件是怎么来的!!

自我感觉TT的算法并不难,就是量太大了,所以我想问问有没有感兴趣的朋友来一起分析,欢迎联系。要具备一定的Android逆向经验,水平相当即可。另外,本项目纯粹用于技术交流,不涉及黑灰产,也不以盈利为目的。


[招生]科锐逆向工程师培训(2025年3月11日实地,远程教学同时开班, 第52期)!

最后于 2天前 被执着的追求编辑 ,原因:
收藏
免费 7
支持
分享
最新回复 (5)
雪    币: 6401
活跃值: (5527)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
+1
4天前
0
雪    币: 221
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
+3
4天前
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
24字节是AES后的最后一个字节
4天前
0
雪    币: 725
活跃值: (5946)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
师傅 请教一下你的这个trace的日志是自己写的trace工具trace的吗
2天前
0
雪    币: 373
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
6
博主 关于tt的jwt刷新机制有研究吗?
2天前
0
游客
登录 | 注册 方可回帖
返回