首页
社区
课程
招聘
[原创]某短视频指纹和纯算 sig3 逆向分析
发表于: 2025-12-16 17:22 14127

[原创]某短视频指纹和纯算 sig3 逆向分析

2025-12-16 17:22
14127

本文章内容仅用于逆向学习,请勿用于黑产行为,如有侵权,请联系本人删除,未经本人允许,不可转载。

这是笔者第一篇关于APP逆向的文章,文笔过于青涩QwQ,还望海涵,属于入门系列文章(大师傅们请绕道QvQ)

QUIC降级:

QUIC是基于 UDP 协议

主流抓包工具,本质上是建立一个 HTTP/HTTPS 代理服务器。它们主要工作在 TCP 协议 之上

因此需要让它放弃使用UDP而使用TCP,因此要先降级处理

正常抓包只有okhttpd走代理,要先降级抓包,jadx搜索cronetConfig找到对应设置配置的地方,打开libageon.so并搜索字符串enable_quic可以找到处理配置的地方

然后就可以正常抓到带sig3的包了

使用reqable进行抓包

字符串搜索sig3很容易找到传入逻辑,就不多说了(在其他例子中可能会出现没找到的情况,可以通过hook hash.put或者其他可能的java方法,很喜欢通过这些方法将header放进去,例如下面这段代码)

Java层入口传入/rest/n/feed/selectionfb4e77xxxxx2541

其中/rest/n/feed/selection是API接口,fb4e77xxxxxxx2541是sig的值

sig是通过传入的request得到的

sig是通过ce6.d$d.d获取的,拿一个栗子

扔给gemini分析一下

第一部分:设备唯一标识 (Device Identifiers)

这些参数用于唯一标识一台设备,是风控最关注的部分。

第二部分:系统与环境信息 (System & Env)

这些参数描述 App 运行的软件环境。

第三部分:业务与请求参数 (Business Logic)

这些参数随用户的具体操作(如刷新首页)而变化。

然后就是一个标准MD5就能获取到649xxxxx879d(之所以跟第一次的不同是因为这不是同一个例子????)

image-20251216164501152

第一个是监控计算签名耗时(可能会拿来做检测?)

第二个是关键计算sig3函数


最后走的是com.kuaishou.android.security.internal.crypto.e.c方法,但是从jadx看该java层代码被严重混淆,jadx无法正确反汇编,因此直接阅读smali

通过gemini可以初步恢复成:

经过分析调用的是com.kuaishou.android.security.internal.crypto.j.f方法,


image-20251216164543778

最后走到了这个函数

是一个so层实现的函数

快手采用了非常经典的“通用分发”模式。它没有为每个功能写一个 JNI 函数

而是写了一个通用的 doCommandNative,通过整数 ID (i4) 来区分要执行什么功能

Ljava.lang.String;@8d18d16这里存储了处理过的字符串MD5(sig)

d7b7d042-d4f2-4012-be60-d97ff2429c17是快手AppKey

com.yxcorp.gifshow.App@9da18de为Native层留一个调用Java方法的对象

Hook registerNative函数获取

libkwsgmain.so

image-20251211163631717

其实就是一个goto指令,直接patch BR X9-> B 0x4631C,IDA就会自己生成一个sub_4631C函数

该软件的花指令基本都是这个,非常简单,只需要patch一个指令即可,可以写个脚本批量匹配特征值进行patch,但是我懒,所以都是手动patch

字符串没找到但是可以通过Hook的结果直接得知对应函数是sub_41680

先unidbg搭架子,把函数运行起来先

unidbg部分在网上就很多了,基本拿来都能直接用,这里就不贴了

64位想正常运行read需要将

unidbg-android/src/main/java/com/github/unidbg/virtualmodule/android/AndroidModule.java

里的throw new BackendException();改为return read(emulator, vm);才可以正常运行

发现多次运行相同的参数结果却不相同,猜测在运行过程中调用了获取时间戳的函数,增加了随机性,在分析之前需要先固定随机

修改gettimeofday64

这样每次运行的结果都是c5d4a4xxxxxxxxx77e3909c9284

目标函数存在大量ollvm混淆的代码,D-810貌似有点bug,所以我写了一个配合unidbg模拟执行然后nop掉一些无用逻辑的IDA插件

b8eK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6K6x3h3&6W2j5#2)9J5k6o6q4G2i4K6u0r3g2s2u0S2j5$3g2o6L8r3g2S2L8R3`.`.

如果有用,球球star⭐

sub_11BDC函数

调用前:

调用后:

可以发现甚至在调用这个函数之前就已经存在结果了,那么肯定在之前就有赋值操作了!

image-20251214201659299

会发现其实就是v100,但是v100没有任何直接赋值的操作!

image-20251214201725361

第二个显然就不可能,第一个就是之前的原语!

我开始怀疑是不是我插件的BUG了?但是这么简单的插件怎么可能有问题呢,unidbg检测一下这个地址附近的值

根据这个trace可以找到调用逻辑

其中有几个函数的部分函数调用是不会调用的,直接可以nop

大致知道调用顺序了,那么开始分析吧,从尾巴开始往上分析

sub_3D5F4image-20251214224136911

这里的v31十分可疑

image-20251214224228829

是通过23578的a2来赋值

image-20251214224310065

这里会发现调用的是下面的两个函数

通过插件能首先发现具有SHA256特征,因此尝试SHA256,但与结果存在较大差异性,然后发现这个函数多传入了两个可疑参数,经过比对分析,发现是HMAC的性能优化的实现,为了避免每次计算签名都重复进行Key ^ 0x36和Key ^ 0x5C的运算,程序预先计算好了这两个状态保存在内存中,经过unidbg打印出对应的值就能看出来,密钥:vWqd4fRXxXxxxxxxxxxeRitxT7VwbK

然后就能写出下面的脚本:

一般来说如果看到是SHA256但输出却不是标准SHA256,有以下几种情况:

HMAC-SHA256(概率最高)

输入被加Salt或者对输入进行了预处理(前后加Salt、转hex、大小端、特殊字符)

魔改初始向量(最好判断)

魔改轮常量(修改K表,找0x428A2F98找不到就是K表被改了)

魔改逻辑/位移量(修改Sigma或Ch/Maj的位移数,很难判断,需要一行一行比对汇编逻辑)

输出后处理(trace一下,也好判断)

.......

然后看到03D5F4函数

image-20251215143650309

这个函数感觉就是C++的某个库函数,涉及到流的操作,但是其实就是一个toHex函数

将类似0xC5->0x63 0x35

通过跟踪trace发现这是较早出现结果的地方

执行过三次这个toHex函数,第一次是HMAC-SHA256的写入,第二次也是某个算法,第三次就是最后的结果了,从最后一次看

image-20251215144742653

image-20251215144851860

但是发现结果是24位的显然是不对的,结果应该是48位才对,应该是后面还有拼接吧

不过这24位确实是结果

这个函数是对全局this指针的初始化,并返回this指针,经过trace发现这里返回结果[3]+8的值都是固定的22

因此0是固定的0x51412200

貌似也是固定的0x1db5ae7f

先dump参数

这个x0是第二次toHex的入参

x1是0x30就是len

x2是CRC32b_poly_Constant_57C78

那就先看x0是怎么获取的

image-20251215155608558

通过sub_1E2C4函数获取

v20依赖全局变量,然后调用26A14

image-20251215160747750

所以v24存储的就是我们在寻找的字符串,然后看到v24是malloc出来的堆内存0x404d3240trace看看

位于2636C函数中,初步判断为白盒AES

根据调试可以知道大致流程如下:

首先在进入这个函数之前会将HMAC-SHA256的结果进行填充\x10到0x30个字节

然后每0x10个字节进去这个函数一次,输出0x10个字节的密文

简单补个环境

$$
\begin{array}{l}\text{state} \leftarrow \text{plaintext} \\\text{AddRoundKey}(\text{state}, k_0) \\\text{for } r = 1 \dots 9 \\\quad \text{SubBytes}(\text{state}) \\\quad \text{ShiftRows}(\text{state}) \\\quad \text{MixColumns}(\text{state}) \\\quad \text{AddRoundKey}(\text{state}, k_r) \\\text{SubBytes}(\text{state}) \\\text{ShiftRows}(\text{state}) \\\text{AddRoundKey}(\text{state}, k_{10}) \\\text{ciphertext} \leftarrow \text{state}\end{array}
$$


[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!

最后于 2025-12-17 16:31 被s1nec-1o编辑 ,原因:
收藏
免费 24
支持
分享
最新回复 (5)
雪    币: 97
活跃值: (1188)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
99999
2025-12-17 06:48
0
雪    币: 7761
活跃值: (7987)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
内容呢?
2025-12-17 14:04
0
雪    币: 20
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
666
2025-12-17 14:49
0
雪    币: 20
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
5
666
2025-12-17 22:22
0
雪    币: 7761
活跃值: (7987)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
图挂了一些,你上传一份md格式到附件
2025-12-19 01:38
0
游客
登录 | 注册 方可回帖
返回