发点库存
1、unidbg调用sig3算法
龙哥之前发布了使用unidbg调用sig3的demo,下载这个demo直接跑。
2、libksgmain.so去花
sig3总所周知实在libksgmain.so中,ida打开改so,Jni_onLoad函数初步预览下。
可以看到此处为花指令,插花的方式和大佬发的一篇ali的libsgmain.so中的花指令类似
函数sub_ce88 在pop时修改了pc指针的值。针对这类花指令可以写脚本进行修复,脚本如下:
去花后可以快乐的f5
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
用ida打开libsgmain.so 跳转到0x2d4b6 地址,f5 该方法发现有明显的sha256算法特征
之前逆向过老版本的sha256,这是魔改的sha256算法,直接用原来的算法,改掉两个数组的值
把a6、a7地址的值dump下来就行。
可以看到结果一致,再次成功还原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 | |
可发现有些值一样有些不一样,通过更改参数进行对比 可总结(只记录不为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 | 0x100000000 - 0x45d = 0xfffffba3
|
0x45d 不就是之前0xbffff6b8 数据之和吗?
5、验证算法正确性
5、1hook+postern进行抓包
具体参考短视频最新版通用quic协议解决方案
5、2对请求重发进行抓包
[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。
最后于 2022-2-26 10:59
被我只是没人要编辑
,原因: