首页
论坛
课程
招聘
[原创]**手910版本sig3 48位算法逆向分析
2022-2-14 23:35 34757

[原创]**手910版本sig3 48位算法逆向分析

2022-2-14 23:35
34757

发点库存

目录

1、unidbg调用sig3算法

龙哥之前发布了使用unidbg调用sig3的demo,下载这个demo直接跑。

2、libksgmain.so去花

sig3总所周知实在libksgmain.so中,ida打开改so,Jni_onLoad函数初步预览下。

 

JNI_OnLoad

 

可以看到此处为花指令,插花的方式和大佬发的一篇ali的libsgmain.so中的花指令类似

 

花指令

 

函数sub_ce88 在pop时修改了pc指针的值。针对这类花指令可以写脚本进行修复,脚本如下:

 

去花后可以快乐的f5

 

去花后JNI_onLoad

 

对应汇编

3、unidbg 调用去花后的libsgmain.so

龙哥提供的unidbg调用的sig3中是调用apk内部的libsgmain

1
DalvikModule dm = vm.loadLibrary("kwsgmain", true);

我们是否可以使用调用外部libsgmain.so的方式来调用我们去花之后的libsgmain.so呢?说干就干,把这行给注释掉,换成

1
DalvikModule dm = vm.loadLibrary(new File("unidbg-android/src/test/resources/ks910/libkwsgmain.so"), true);

RUN RUN RUN RUN RUN(蒙多,想怎么RUN就怎么RUN)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[23:44:46 552]  INFO [com.github.unidbg.linux.AndroidElfLoader] (AndroidElfLoader:459) - libkwsgmain.so load dependency libc++_shared.so failed
stack  ts
[23:44:46 633]  INFO [com.github.unidbg.linux.ARM32SyscallHandler] (ARM32SyscallHandler:828) - pthread_clone child_stack=RW@0x403be930, thread_id=1, fn=RX@0x401837f5[libc.so]0x3f7f5, arg=RW@0x403be930, flags=[CLONE_VM, CLONE_FS, CLONE_FILES, CLONE_SIGHAND, CLONE_THREAD, CLONE_SYSVSEM, CLONE_SETTLS, CLONE_PARENT_SETTID, CLONE_CHILD_CLEARTID]
stack  ts
stack  ts
JNIEnv->GetStringUtfChars("/data/app/com.smile.gifmaker-oyRnT1esU1Pf5iDY6JKtjA==/base.apk") was called from RX@0x400451a5[libkwsgmain.so]0x451a5
JNIEnv->ReleaseStringUTFChars("/data/app/com.smile.gifmaker-oyRnT1esU1Pf5iDY6JKtjA==/base.apk") was called from RX@0x4000e305[libkwsgmain.so]0xe305
stack  ts
stack  ts
stack  ts
stack  ts
JNIEnv->GetStringUtfChars("d7b7d042-d4f2-4012-be60-d97ff2429c17") was called from RX@0x40051e53[libkwsgmain.so]0x51e53
stack  ts
JNIEnv->GetStringUtfChars("com.smile.gifmaker") was called from RX@0x4000de87[libkwsgmain.so]0xde87
JNIEnv->ReleaseStringUTFChars("com.smile.gifmaker") was called from RX@0x4000e305[libkwsgmain.so]0xe305
[23:44:47 663]  WARN [com.github.unidbg.arm.AbstractARMEmulator] (AbstractARMEmulator$1:58) - memory failed: address=0x7084, size=1, value=0x0, PC=unidbg@0x7084, LR=RX@0x4004d68d[libkwsgmain.so]0x4d68d
[23:44:47 663]  WARN [com.github.unidbg.AbstractEmulator] (AbstractEmulator:389) - emulate RX@0x40053129[libkwsgmain.so]0x53129 exception sp=unidbg@0xbfffec88, msg=unicorn.UnicornException: Invalid memory fetch (UC_ERR_FETCH_UNMAPPED), offset=1003ms
Exception in thread "main" java.lang.NullPointerException
    at com.ks910.kwsgmain910.callInit(kwsgmain910.java:97)
    at com.ks910.kwsgmain910.main(kwsgmain910.java:73)

3、1 替换外部so报错?尝试查找原因

想法是美好的,现实是残酷的报错了----

 

会不会是patch的so有问题?

 

为了验证这一点,我们使用apk原始so,使用加载外部so的方式来进行加载,结果也出错 ,无奈只有换个思路加载外部so

3、2 换个思路加载外部so

竟然demo只能加载apk内部so的方式才能运行成功,我们是否可以通过把apk lib目录下的原始so替换成我们已经patch之后的so,来让demo程序加载内部so的时候加载我们patch的so?

 

答案是可以,sig3已被计算出来

1
2
JNIEnv->ReleaseStringUTFChars("d7b7d042-d4f2-4012-be60-d97ff2429c17") was called from RX@0x4000e305[libkwsgmain.so]0xe305
result:d3c2b2915f3804b59b9b9899f95a9abe878c3ae0868a8492

4、trace还原算法

上一步为什么去花?就是为了trace分析算法的时候能少些干扰,另外还可以减少trace后的指令。

4、1trace配置

 

在get_NS_sig3函数开始trace,过滤掉一些非so的trace。 开始trace!

4、2 从trace文件中寻找输入

已知unidbg中的输入为:

1
/rest/n/comment/list/firstPagefcac84fe7071434ad19cc4771890acef

使用谷歌浏览器的hackbar插件对输入的数据进行hexdump

1
2f726573742f6e2f636f6d6d656e742f6c6973742f6669727374506167656663616338346665373037313433346164313963633437373138393061636566

用01edit打开trace文件,以4位一组进行搜索,即搜索0x2f726573

 

trace搜索结果

 

用ida打开libsgmain.so 跳转到0x2d4b6 地址,f5 该方法发现有明显的sha256算法特征

 

 

 

之前逆向过老版本的sha256,这是魔改的sha256算法,直接用原来的算法,改掉两个数组的值

 

 

把a6、a7地址的值dump下来就行。

 

ida中结果位置

 

trace中结果

 

算法还原结果

 

可以看到结果一致,再次成功还原sha256

4、3 抽丝剥茧寻找下一步

为了减少trace文件对我们的干扰,把结果之前的代码全部删除,再次搜索sha256之后的结果,无果。我们尝试搜索下字节。

 

找到算法部分

 

 

hook一下 a2

 

 

内容就是对sha256进行乱序并扩张内容为0x10个0x10字节.v24 是什么? 交叉引用看下

 

 

 

算法明了了,不能说和mt的动态计算sha256的key的算法有什么不同,只能说完全一摸一样。。。 把数据dump下来,开始对比结果

 

 

4、4 通过结果进行回溯

 

 

每次运行demo发现sig3的结果都不同,r1和r0的值进行了改变。使用unidbg traceWrite 0xbffff6b8处的地址,查看内存情况进行对比

1
emulator.traceWrite(0xbffff6b8L, 0xbffff6b8L + 0x16);
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
one
### Memory WRITE at 0xbffff6bc, data size = 4, data value = 0x0
### Memory WRITE at 0xbffff6c0, data size = 4, data value = 0x0
### Memory WRITE at 0xbffff6c4, data size = 4, data value = 0x0
### Memory WRITE at 0xbffff6c8, data size = 4, data value = 0x0
### Memory WRITE at 0xbffff6cc, data size = 4, data value = 0x0
### Memory WRITE at 0xbffff6b8, data size = 4, data value = 0x5141
### Memory WRITE at 0xbffff6ba, data size = 2, data value = 0x22
### Memory WRITE at 0xbffff6bc, data size = 4, data value = 0x2acf568f
### Memory WRITE at 0xbffff6c4, data size = 4, data value = 0x2306c567         // same
### Memory WRITE at 0xbffff6c8, data size = 4, data value = 0x61ba1ea6
### Memory WRITE at 0xbffff6c0, data size = 4, data value = 0x1
### Memory WRITE at 0xbffff6cc, data size = 4, data value = 0xd00
### Memory WRITE at 0xbffff6cc, data size = 4, data value = 0x2c000d00
 
two
### Memory WRITE at 0xbffff6bc, data size = 4, data value = 0x0
### Memory WRITE at 0xbffff6c0, data size = 4, data value = 0x0
### Memory WRITE at 0xbffff6c4, data size = 4, data value = 0x0
### Memory WRITE at 0xbffff6c8, data size = 4, data value = 0x0
### Memory WRITE at 0xbffff6cc, data size = 4, data value = 0x0
### Memory WRITE at 0xbffff6b8, data size = 4, data value = 0x5141
### Memory WRITE at 0xbffff6ba, data size = 2, data value = 0x22
### Memory WRITE at 0xbffff6bc, data size = 4, data value = 0x6c4d7d4f
### Memory WRITE at 0xbffff6c4, data size = 4, data value = 0x2306c567    //same
### Memory WRITE at 0xbffff6c8, data size = 4, data value = 0x61ba1ec1
### Memory WRITE at 0xbffff6c0, data size = 4, data value = 0x1
### Memory WRITE at 0xbffff6cc, data size = 4, data value = 0xd00
### Memory WRITE at 0xbffff6cc, data size = 4, data value = 0x6a000d00

可发现有些值一样有些不一样,通过更改参数进行对比 可总结(只记录不为0的数据)

地址 固定/or改变 附加
0xbffff6b8 0x5141 固定
0xbffff6ba 0x22 固定
0xbffff6bc 0x6c4d7d4f 随机
0xbffff6c4 0x2306c567 输入相同固定
0xbffff6c8 0x61ba1ec1 随机
0xbffff6c0 0x1 固定 每调用一个sig3加1
0xbffff6cc 0xd00 固定
0xbffff6cc 0x6a000d00 固定 6a位sig3最后两位
 

(经后面发现,如果连续调用两次sig3,则随机部分都不会改变,只有0xbffff6c0处的值会根据调用次数而增加)

 

通过这张表,最主要的工作就是0x2306c567和0x6a数据的来源,在trace文件中搜索

 

 

一个数和0xfffffff进行异或???

 

 

最终根据trace文件查找如下函数。

 

接下来就是0x6a的值 同样在trace文件中搜索。

 

1
0xfffffba3 & 0xFF = 0xa3

1
0x100000000 - 0x45d = 0xfffffba3

 

0x45d 不就是之前0xbffff6b8 数据之和吗?

5、验证算法正确性

5、1hook+postern进行抓包

具体参考短视频最新版通用quic协议解决方案

5、2对请求重发进行抓包

原始sig3

 

算法计算后的sig3

 

替换后结果


【看雪培训】《Adroid高级研修班》2022年春季班招生中!

最后于 2022-2-26 10:59 被hczhong编辑 ,原因:
收藏
点赞5
打赏
分享
打赏 + 50.00雪花
打赏次数 1 雪花 + 50.00
 
赞赏  Editor   +50.00 2022/03/18 恭喜您获得“雪花”奖励,安全圈有你而精彩!
最新回复 (6)
雪    币: 667
活跃值: 活跃值 (1126)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
伟叔叔 活跃值 2022-2-15 15:31
2
0
trace花了多久啊
雪    币: 359
活跃值: 活跃值 (390)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
陈某人 活跃值 2022-2-17 16:02
3
0
替换patch后的so,重打包还是会报错
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
都怪这月色 活跃值 2022-2-18 10:31
4
0
有偿学习逆向:麻烦加q:871172489
雪    币: 514
活跃值: 活跃值 (313)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
a峰 活跃值 2022-3-11 15:36
5
0
雪    币: 740
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
_thouger 活跃值 2022-4-2 13:47
6
0
针对这类花指令可以写脚本进行修复,脚本如下:
-------------
下面的脚本是我没加载出来,还是丢包了??
雪    币: 1
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
手把手教我吗 活跃值 2022-4-14 20:24
7
0
大佬,10版本的怎么抓包,怎么我用了那种方法也抓不了了
游客
登录 | 注册 方可回帖
返回