首页
论坛
课程
招聘
[逆向分析] [原创]某书shield分析及算法还原
2021-5-4 02:16 4526

[逆向分析] [原创]某书shield分析及算法还原

2021-5-4 02:16
4526

最近闲来无事儿,找个app学习学习

 

xhs版本:6.87.0.1

静态分析

首先抓包寻找入口点,通过字符串"/api/sns/v4/user/login/code"定位到接口类

通过交叉引用找到调用处,通过一些字符串及代码特征可得知使用了retrofit网络库,retrofit本质上是对okhttp的封装,因此hook okhttp的相关函数可定位到发包位置,也可通过代码特征进行定位。


通过搜索""Base URL required.""字符串定位到retrofit的build函数,交叉引用查找在哪里初始化

数量不多,hook打印堆栈查找对应功能是哪个函数调用,这里frida启动应用会崩溃,过掉了几个检测点依然如此,没有继续研究,使用xposed hook。有知道原因的大佬望指点一下。

1
2
3
4
5
6
7
8
9
2021-04-16 22:51:08.032 26418-26418/? E/xhs:     at m.x.z0.g.i.a(<Xposed>:-1)
2021-04-16 22:51:08.032 26418-26418/? E/xhs:     at m.x.o1.d0.x.a(XhsNetworkModule.kt:108)
2021-04-16 22:51:08.032 26418-26418/? E/xhs:     at m.x.o1.d0.x.h(XhsNetworkModule.kt:2)
2021-04-16 22:51:08.032 26418-26418/? E/xhs:     at m.x.o1.d0.x.i(XhsNetworkModule.kt:23)
2021-04-16 22:51:08.032 26418-26418/? E/xhs:     at com.xingin.xhs.app.SkynetApplication.onCreate(SkynetApplication.kt:2)
2021-04-16 22:51:08.032 26418-26418/? E/xhs:     at com.xingin.xhs.app.MainApplication.onCreate(MainApplication.kt:4)
2021-04-16 22:51:08.032 26418-26418/? E/xhs:     at com.xingin.xhs.app.XhsApplication.initApplication(XhsApplication.kt:17)
2021-04-16 22:51:08.032 26418-26418/? E/xhs:     at com.xingin.xhs.app.XhsApplication.beforeInitApplication(XhsApplication.kt:16)
2021-04-16 22:51:08.032 26418-26418/? E/xhs:     at com.xingin.xhs.app.XhsApplication.onCreate(XhsApplication.kt:6)

通过堆栈对代码调用流程进行分析,最后定位到XhsHttpInterceptor类,由于对okhttp Interceptor技术不太了解,这里走了不少弯路。

这个类注册了四个native方法,ida打开so看看对应方法的实现。

 


 

initializeNative主要进行初始化操作,获取一些Java相关的方法。

 

initialize读取s.xml文件,获取之后计算shield的相关数据。

对main_hmac字段进行解密操作

通过一些特征发现是非标准的aes算法
AES Init方法

AES Decrypt方法

AES Encrypt方法

在加解密过程中,加密用Tbox1-4,解密用Tbox5-8,前9轮用T,最后一轮用Sbox。
至此initialize函数分析完成。

 

接下来看看intercept函数,经过调试得知程序走这个分支

首先看105B0这个函数,该函数主要对请求数据进行MD5运算。

对AES解密的数据分别异或0x36和0x5C计算MD5。


这里的MD5算法也不是标准的,心态崩了啊。
MD5 Init函数

MD5 Update函数

MD5 Trans函数

以上操作执行完以后,通过反射调用方法读取请求数据。

读取成功后对请求数据进行MD5计算,这里使用的ctx为AES解密结果xor 0x36结果的MD5 ctx;计算成功后对计算的结果再一次进行MD5,这里使用的ctx为AES解密结果xor 0x5C结果的MD5 ctx。
至此105B0函数执行完成。

 

读取build,deviceid

进入sub_404E8函数,初始化结构,保存信息,这里静态没看出什么来,动态调调看吧

继续对数据进行处理,看字符串相关信息猜了个大概函数功能

对处理完成后的数据进行加密。
初始化加密表

加密函数,就简单的异或操作。

对加密后的数据进行处理,根据相关字符串猜测,具体数据调试看。
图片描述
最后对处理完成的数据base64编码并拼接XY就是shield的值了。

动态分析

调试过程中发现initialize方法仅调用了一次,frida无法启动应用,没辙主动调用吧

1
2
3
4
5
6
7
8
9
10
function call_init() {
    Java.perform(() => {
        //var currentApplication = Java.use("android.app.ActivityThread").currentApplication();
        //var context = currentApplication.getApplicationContext();
        var XhsHttpInterceptor = Java.use('com.xingin.shield.http.XhsHttpInterceptor')
        var cls = Java.use('m.x.y0.a.a')
        var cls1 = Java.use('m.x.o1.d0.x$c')
        XhsHttpInterceptor.$new("main",cls1.$new())
    })
}

成功断下

查看AES解密后的结果

1
2
3
4
5
6
02 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00
51 F9 44 08 66 D7 46 3C  F9 67 7D 54 A1 47 0D 8B
66 A1 D1 3B 1E CD 91 38  0C 53 AC 80 66 BC BB 8E
9D E2 0A B6 80 19 13 70  61 AD 31 86 03 67 7F 42
BD FD 81 B7 E0 A7 49 4B  8E 0C 15 AE EE 1D D7 EA
10 10 10 10 10 10 10 10  10 10 10 10 10 10 10 10

sub_404E8函数

1
2
3
4
5
6
7
C0 0D 8F 97
            app_id
01 00 00 00 01 AF FA EC  02 00 00 00 07 00 00 00
                          build       deviceId
24 00 00 00 10 00 00 00  38 51 B0 95 20 5F 78 8A
md5结果
60 10 1E 83 29 00 00 00  00 00 00 00 00 00 00 00

Payload2ByteArray函数,拼接了build,deviceId和计算好的MD5

1
2
3
4
5
6
7
处理后结果
00 00 00 01 EC FA AF 01  00 00 00 02 00 00 00 07
00 00 00 24 00 00 00 10  36 38 37 30 32 31 33 37
30 63 35 39 32 35 39 2D  37 65 39 31 2D 33 65 38
62 2D 62 38 66 32 2D 33  35 38 35 35 61 38 35 36
35 62 36 BF C9 92 0E BC  ED 07 2E C7 8D FE 2E DF
E1 54 1C

初始化加密表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
表结构如下所示:
7C 00 00 00
2E 00 00 00 0E 00 00 00  3D 00 00 00 09 00 00 00
32 00 00 00 E3 00 00 00  1C 00 00 00 87 00 00 00
C9 00 00 00 B3 00 00 00  2D 00 00 00 B1 00 00 00
2B 00 00 00 DD 00 00 00  20 00 00 00 0B 00 00 00
C3 00 00 00 28 00 00 00  5C 00 00 00 0F 00 00 00
7B 00 00 00 12 00 00 00  53 00 00 00 0C 00 00 00
2F 00 00 00 92 00 00 00  23 00 00 00 30 00 00 00
CE 00 00 00 50 00 00 00  D0 00 00 00 40 00 00 00
1F 00 00 00 45 00 00 00  33 00 00 00 3B 00 00 00
95 00 00 00 B2 00 00 00  15 00 00 00 BC 00 00 00
34 00 00 00 89 00 00 00  E6 00 00 00 D5 00 00 00
39 00 00 00 68 00 00 00  78 00 00 00 F1 00 00 00
80 00 00 00 7F 00 00 00  C1 00 00 00 CA 00 00 00
3E 00 00 00 71 00 00 00  52 00 00 00 7A 00 00 00
5E 00 00 00 E7 00 00 00  A4 00 00 00 37 00 00 00
A5 00 00 00 69 00 00 00  D1 00 00 00 4C 00 00 00
73 00 00 00 B6 00 00 00  5B 00 00 00 FE 00 00 00
16 00 00 00 CF 00 00 00  55 00 00 00 CB 00 00 00
C0 00 00 00 F9 00 00 00  24 00 00 00 10 00 00 00
A8 00 00 00 6B 00 00 00  E0 00 00 00 62 00 00 00
8C 00 00 00 63 00 00 00  D9 00 00 00 BD 00 00 00
DA 00 00 00 31 00 00 00  F3 00 00 00 96 00 00 00
E4 00 00 00 75 00 00 00  5D 00 00 00 F7 00 00 00
79 00 00 00 22 00 00 00  57 00 00 00 DE 00 00 00
BF 00 00 00 91 00 00 00  86 00 00 00 EA 00 00 00
85 00 00 00 97 00 00 00  4D 00 00 00 83 00 00 00
00 00 00 00 A9 00 00 00  84 00 00 00 14 00 00 00
27 00 00 00 1A 00 00 00  17 00 00 00 ED 00 00 00
E1 00 00 00 1B 00 00 00  6F 00 00 00 41 00 00 00
59 00 00 00 A2 00 00 00  99 00 00 00 FC 00 00 00
4B 00 00 00 1E 00 00 00  A7 00 00 00 74 00 00 00
AB 00 00 00 7D 00 00 00  88 00 00 00 5A 00 00 00
51 00 00 00 E2 00 00 00  BE 00 00 00 A6 00 00 00
77 00 00 00 67 00 00 00  58 00 00 00 11 00 00 00
0D 00 00 00 A0 00 00 00  8F 00 00 00 08 00 00 00
2A 00 00 00 72 00 00 00  D2 00 00 00 C2 00 00 00
9B 00 00 00 36 00 00 00  D7 00 00 00 F2 00 00 00
70 00 00 00 35 00 00 00  8E 00 00 00 D3 00 00 00
03 00 00 00 B7 00 00 00  B9 00 00 00 C8 00 00 00
2C 00 00 00 93 00 00 00  B0 00 00 00 EE 00 00 00
8D 00 00 00 07 00 00 00  F8 00 00 00 47 00 00 00
8B 00 00 00 E9 00 00 00  90 00 00 00 04 00 00 00
46 00 00 00 94 00 00 00  D4 00 00 00 49 00 00 00
4E 00 00 00 B5 00 00 00  D6 00 00 00 A1 00 00 00
AC 00 00 00 4F 00 00 00  BB 00 00 00 DC 00 00 00
FF 00 00 00 18 00 00 00  BA 00 00 00 AF 00 00 00
C4 00 00 00 26 00 00 00  6E 00 00 00 9E 00 00 00
6D 00 00 00 3A 00 00 00  5F 00 00 00 C7 00 00 00
82 00 00 00 44 00 00 00  AE 00 00 00 CD 00 00 00
8A 00 00 00 AD 00 00 00  3C 00 00 00 38 00 00 00
01 00 00 00 A3 00 00 00  DF 00 00 00 C5 00 00 00
05 00 00 00 02 00 00 00  F4 00 00 00 F0 00 00 00
06 00 00 00 13 00 00 00  3F 00 00 00 EF 00 00 00
29 00 00 00 64 00 00 00  FD 00 00 00 66 00 00 00
25 00 00 00 60 00 00 00  EB 00 00 00 E8 00 00 00
61 00 00 00 7E 00 00 00  FA 00 00 00 54 00 00 00
9A 00 00 00 FB 00 00 00  D8 00 00 00 F5 00 00 00
B4 00 00 00 48 00 00 00  76 00 00 00 43 00 00 00
65 00 00 00 6A 00 00 00  EC 00 00 00 9C 00 00 00
1D 00 00 00 F6 00 00 00  0A 00 00 00 E5 00 00 00
9F 00 00 00 42 00 00 00  6C 00 00 00 C6 00 00 00
B8 00 00 00 CC 00 00 00  9D 00 00 00 AA 00 00 00
DB 00 00 00 98 00 00 00  21 00 00 00 81 00 00 00
56 00 00 00 4A 00 00 00  19 00 00 00

SignRequest2ByteArray函数

1
2
3
4
5
6
7
8
9
处理后的结果:
00 00 00 01
00 00 00 01 00 00 00 53  00 00 00 53 35 16 11 ED
31 1B 52 1B 0F DF DC FA  A0 8B 3A 52 86 99 3B 45
6B E9 46 E3 70 06 7B E1  54 45 AE 45 C5 D7 B5 97
B4 62 45 9D FF AA E9 5E  CF C3 7F D4 9F 7E 83 AA
64 12 0C 4D 14 6D 8D 61  EA FC D9 2D 65 D4 E2 2A
18 EE D1 1E 56 96 C7 53  F6 C5 66 89 C2 A3 A7 00
68 8C CF B4 27

代码还原

没得说了就剩头铁了,F5,Trace大法好。
代码写的比较乱可能还有奇奇怪怪的问题,各位看官勿怪。
GitHub:https://github.com/smallsun107/xhsShield/


[看雪官方培训] Unicorn Trace还原Ollvm算法!《安卓高级研修班》2021年6月班火热招生!!

最后于 2021-5-4 02:33 被岁月。编辑 ,原因:
收藏
点赞6
打赏
分享
最新回复 (8)
雪    币: 1865
活跃值: 活跃值 (1382)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
virjar 活跃值 1 2021-5-6 09:28
2
1
都魔改了,还这么不小心。
建议:
1. 使用宏替代函数,避免被native trace
2. 能inline 尽量inline,避免被native trace
3. aes魔改的核心流程,不要考虑模块化,手动写到一个函数里面(手动人工inlne)

ollvm符号混淆的还是可以适当加一点儿。

现在ollvm能被手撕的最大原因,就是因为模块化太好,留下了大量可以被hook的sub function。要是整个算法就一个function body,没有其他sub route,我看他怎么trace
雪    币: 2508
活跃值: 活跃值 (515)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
岁月。 活跃值 1 2021-5-6 10:28
3
0
virjar 都魔改了,还这么不小心。 建议: 1. 使用宏替代函数,避免被native trace 2. 能inline 尽量inline,避免被native trace 3. aes魔改的核心流程,不要 ...
大佬提的防护方案还是很到位
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
王小煦 活跃值 2021-5-7 15:50
4
0
最新刚好在研究最新版的xhs,一起讨论下如何?qq 1585490469
雪    币: 438
活跃值: 活跃值 (347)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
mb_foyotena 活跃值 2021-5-7 19:27
5
0
virjar 都魔改了,还这么不小心。 建议: 1. 使用宏替代函数,避免被native trace 2. 能inline 尽量inline,避免被native trace 3. aes魔改的核心流程,不要 ...
你错了, 一整块更好trace
雪    币: 1865
活跃值: 活跃值 (1382)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
virjar 活跃值 1 2021-5-7 19:28
6
0
mb_foyotena 你错了, 一整块更好trace
为啥呢,大佬
雪    币: 4521
活跃值: 活跃值 (1181)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
尐进 活跃值 2021-5-10 12:58
7
0
一整块更好trace
雪    币: 0
活跃值: 活跃值 (66)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
laonaa 活跃值 6天前
8
0
你这开源不地道了啊 多少灰产要谢谢你?
雪    币: 931
活跃值: 活跃值 (461)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
Mr.YX 活跃值 6天前
9
0
老哥,你这个AES算法就是标准的。https://blog.csdn.net/essity/article/details/86715866
游客
登录 | 注册 方可回帖
返回