猫大人 发表于 2022-12-29 22:59

iOS端Wtoken浅析

网上看到一些前辈对某SDK做过一些分析,自己也来实践操作一下,对自己平时分析的过程做一个简单记录

## 一.获取样本
样本来源为某waf2.0:
```
0002_84288D08C9374C3BD0201E3A8581A637A4F10635D6C1AD364FF9AD35A3073D4AAD68B431ACBEB332ABC3AC3CA8CB7A3B8815EA47C900QufkJeD6QRw50f/FZmE56tVVB3+Xf7tsOWNwpGmRtV9c+9XVaEGi91mRse0WDGYDqSKE/Fi4XTybRySzpSqrj1b5OkdVEbBlAX1Y0laawyer+eMW3IR7qcVnEbup+zYaNy0rR4i8OSKMf/DrpghjUfkyybAhFBTgzjK5+dvGugTLWxfHU2gnYdnn79x3D/jz/EJEpBrN3O/FdanEn8S5wb0VbqzQ/iRbmMZxwq6hUJzCy7CvSH5gjDPX+8BpJUwaxVAy2VR5EhvhDFqPvm/YAuY6ZcfATB2Zh5x5kVkDUFWZGWtNp3OfWodBY6oT34iNKl7/DJl0v97g4JYEcUlXkVAUNTIb1+hAhRZb6stIR3DJoIO9LVAVTYBN5QzURu017Ob6/NjHUOwAd38REY5M6VLITharAN30Z61J0cYAp/xio4RBhojNqWl2FwPRnKbr
```
0002应该是该风控的版本号
我们这次来的目的就是为了把 wtoken 给完全解开

## 二.开始分析
根据官网的说明文档
```
if(![initialize:@"****OpKLvM6zliu6KopyHIhmneb_****u4ekci2W8i6F9vrgpEezqAzEzj2ANrVUhvAXMwYzgY_****vc51aEQlRovkRoUhRlVsf4IzO9dZp6nN_****Wz8pk2TDLuMo4pVIQvGaxH3vrsnSQiK****"])
{
      NSLog(@"初始化失败");
      return;
}
NSString *signBody =@"hello";
NSString *wToken= [ vmpSign:];
NSLog(@"wToken== %@",wToken);
```
### 1.固定随机数
首先是hook initialize 方法,拿到其中的appkey
然后hook vmpSign,固定入参,想办法把输出结果固定下来
首先拦截发送的网络请求,将返回值固定下来.

然后发现生成的结果还是在变,分析其中的导入函数,hook其中可以产生随机值的地方

在hook   arc4random 和 gettimeofday 终于将生成的结果固定唯一


### 2.分析结构组成
wtoken基本由四部分组成

版本号
```
0002_
```
时间戳
```
84288D08C9
```
整体的签名(前两位37为随机值,确定签名所使用的方法)
```
374C3BD0201E3A8581A637A4F10635D6C1AD364FF9AD35A3073D4AAD68B431ACBEB332ABC3AC3CA8CB7A3B8815EA47C900
```
设备信息
```
QufkJeD6QRw50f/FZmE56tVVB3+Xf7tsOWNwpGmRtV9c+9XVaEGi91mRse0WDGYDqSKE/Fi4XTybRySzpSqrj1b5OkdVEbBlAX1Y0laawyer+eMW3IR7qcVnEbup+zYaNy0rR4i8OSKMf/DrpghjUfkyybAhFBTgzjK5+dvGugTLWxfHU2gnYdnn79x3D/jz/EJEpBrN3O/FdanEn8S5wb0VbqzQ/iRbmMZxwq6hUJzCy7CvSH5gjDPX+8BpJUwaxVAy2VR5EhvhDFqPvm/YAuY6ZcfATB2Zh5x5kVkDUFWZGWtNp3OfWodBY6oT34iNKl7/DJl0v97g4JYEcUlXkVAUNTIb1+hAhRZb6stIR3DJoIO9LVAVTYBN5QzURu017Ob6/NjHUOwAd38REY5M6VLITharAN30Z61J0cYAp/xio4RBhojNqWl2FwPRnKbr
```

### 3.加密过程分析
整个SDK混淆的比较严重,插入了大量花指令来阻止IDA的分析

首先,找到的VMP调用外部函数的调用点

通过x8寄存器跳转到不同的函数里,通过打印x8的流转,然后用Frida来辅助分析.基本可以得到整个加密过程的基本逻辑

其中的加解密就是一些移位异或加减之类的,最后再进行一次AES加密生成的

比如通过字节码的补位来判断采取的加密方式



在这里,可以在lldb中采用手动给w9赋值的方式还原所有的加密方法
```
p w9 = 0
```
比如当 w9 为 0 时,采取的偏移跳转第一个加密块 loc_100038188



从图上可以清楚的看出来,这个一个比特位互换的操作 例如 0xAB => 0xBA

还原成C的话就是
```
new_byte = ((orig_byte << 4) | (orig_byte >> 4)) & 0xff
```
其他的加密也大同小异,剩下的15种加密方式就不一一列举了.


还有一部分就是对传进来的body进行签名操作
1.首先body 拼接 &14b8_ 和之前采集的设备信息做一次sha256,当然这个sha256不是标准算法
2.然后再生成的结果中取 位做 hmac 运算
3.拼接 14b8 + d330 之后,根据生成的随机值37做加密运算,还是异或之类的操作
4.生成sign


最后解密出来的数据基本如下
```
num: data:
num: data:
num: data:
num: data:
num: data:
num: data:
num: data:
num: data:
num: data:
num: data:
num: data:
num: data:
num: data:
num: data:
num: data:
num: data:
num: data:
num: data:
num: data:
num: data:
num: data:
num: data:
num: data:
num: data:
num: data:
num: data:
num: data:
num: data:
num: data:
num: data:
num: data:
num: data:
num: data:
```
数据有一部分进行了加密或者脱密处理,使我们不能直接看到原始信息

但是在分析过程中,SDK获取的信息基本为:

* 环境检测
* 动态库检测
* 调试检测
* hook检测

越狱文件检测
```
/Applications/Cydia.app
/Library/MobileSubstrate/MobileSubstrate.dylib
/bin/bash
/usr/sbin/sshd
/etc/apt
/usr/bin/cycript
/usr/bin/gdbhd
```
dladdr检测列表
```
x0 = 0x00000001a42cefa0libsystem_c.dylib`sysctl

x0 = 0x00000001a42dd990libsystem_c.dylib`fopen

x0 = 0x00000001a42f7c08libsystem_c.dylib`getenv

x0 = 0x00000001a44ad760libsystem_kernel.dylib`stat

x0 = 0x00000001a44b9608libdyld.dylib`_dyld_get_image_name

x0 = 0x00000001a44b9710libdyld.dylib`dladdr

x0 = 0x00000001a4597598CoreFoundation`-

x0 = 0x00000001a459ceb8CoreFoundation`+

x0 = 0x00000001a45b1a74CoreFoundation`+

x0 = 0x00000001a45b9600CoreFoundation`+

x0 = 0x00000001a495b73cSystemConfiguration`CNCopyCurrentNetworkInfo

x0 = 0x00000001a4979a84Foundation`+

x0 = 0x00000001a497d624Foundation`+

x0 = 0x00000001a497e030Foundation`-

x0 = 0x00000001a4980f90Foundation`-

x0 = 0x00000001a498690cFoundation`-

x0 = 0x00000001a4996978Foundation`-

x0 = 0x00000001a49a1db0Foundation`+

x0 = 0x00000001a49b69e4Foundation`-

x0 = 0x00000001a49b6c6cFoundation`-

x0 = 0x00000001a49b7124Foundation`-

x0 = 0x00000001a49ff65cFoundation`-

x0 = 0x00000001a79082ccCFNetwork`CFNetworkCopySystemProxySettings

x0 = 0x00000001a83d8194UIKitCore`-

x0 = 0x00000001a83d81f0UIKitCore`-

x0 = 0x00000001a83d83b0UIKitCore`-

x0 = 0x00000001a83d8468UIKitCore`-

x0 = 0x00000001a83d8cacUIKitCore`-

x0 = 0x00000001a83d8cb8UIKitCore`-

x0 = 0x00000001a83e4198UIKitCore`-

x0 = 0x00000001a8eaab3cCoreTelephony`-

x0 = 0x00000001a8eaab4cCoreTelephony`-

x0 = 0x00000001a8eaab5cCoreTelephony`-

x0 = 0x00000001a8eaab6cCoreTelephony`-

x0 = 0x00000001a8eade3cCoreTelephony`-

x0 = 0x00000001a8eae2c4CoreTelephony`-

x0 = 0x00000001bd6b5cc4AdSupport`-

x0 = 0x00000001bd6b5d28AdSupport`-
```

## 三.总结
时间过去的有点久,很多入口函数忘记在哪里了,从技术角度来讲确实逆向的难度比较大,主要是掺杂了大量的自定义算法,比如在拼接设备信息之后,按照字节的补位数一共有16种加密算法,还有魔改的sha256,hash算法,大部分时间都花在还原这一部分算法上面了.整体难度很大

mikeshan 发表于 2023-4-27 11:32

大佬太厉害了吧 膜拜
我最近也在尝试hook抖音 用的monkeydev的框架 但是用facebook开源的fishhook替换c函数实现调用之后就会crash
这是做了什么antifishhook的机制吗?

7Wen 发表于 2022-12-30 13:50

看的有点晕,回头自己试一下。不过大佬发这个东西,外面都卖的很贵很贵的,会不会被报复啊哈哈,断人财路了

lhp462 发表于 2022-12-30 11:25

学到了,谢谢分享

zhangwei2002 发表于 2022-12-30 11:35

大佬, ios16.0可以支持越狱吗?

dofu05jj7uu 发表于 2022-12-30 13:32

大佬牛批,谢谢了!

WAITME66 发表于 2022-12-30 14:34

谢谢分享,学学楼主

li21546 发表于 2022-12-30 14:39

金贵可以贵哦管理库韩国无了hi李欧派hi了hi了

HOTian88888888 发表于 2022-12-30 17:19

挺好的,希望对我们有帮助

吴了凡 发表于 2022-12-30 17:37

666,kanbudong zhichizhichi

ws920222 发表于 2022-12-30 21:31

虽然现在还看不懂,但是还是要支持大佬
页: [1] 2 3
查看完整版本: iOS端Wtoken浅析