CISCN2024
Rev
asm_re
看汇编,简单转换一下逻辑,大概是这样
1 |
|
导出一下密文
爆破flag
exp
1 | enc = [0x1FD7, 0x21B7, 0x1E47, 0x2027, 0x26E7, 0x10D7, 0x1127, 0x2007, 0x11C7, 0x1E47, 0x1017, 0x1017, 0x11F7, 0x2007, 0x1037, 0x1107, 0x1F17, 0x10D7, 0x1017, 0x1017, 0x1F67, 0x1017, 0x11C7, 0x11C7, 0x1017, 0x1FD7, 0x1F17, 0x1107, 0x0F47, 0x1127, 0x1037, 0x1E47, 0x1037, 0x1FD7, 0x1107, 0x1FD7, 0x1107, 0x2787] |
android_re
主要加密在inspect里面
key和iv都在native 层JNI里
都挺复杂的,静态不好分析
考虑动态,frida hook梭
1 | function hook() { |
结果发现getkey返回值不是Mofified UTF-8,导致程序崩溃
所以尝试直接hook JNI函数
1 | function hook() { |
得到
1 | key = b"A8UdWaeq" |
exp
1 | import base64 |
rust_baby
看看字符串窗口
有明显base64表和数据
跟进一下找到主函数 sub_14000298A
先解看看这数据是什么
1 | { |
大致判断igdydo19TVE13ogW1AT5DgjPzHwPDQle1X7kS8TzHK8S5KCu9mnJ0uCnAQ4aV3CSYUl6QycpibWSLmqm2y/GqW6PNJBZ/C2RZuu+DfQFCxvLGHT5goG8BNl1ji2XB3x9GMg9T8Clatc=
是最后的密文
base64解码一下最终密文,可以得知输入长度是104
开始调试,输入长度伪104
的字符串,这里对输入进行分组
355
行对数据进行了加密处理,静态看比较复杂
直接看结果,前两位-1然后两位不变,再两位+1,最后两位+2
然后加密完后每一位异或0x33
中间一大段是用这这两串来进行一系列操作 "whatadoor":"1145141919810WTF"
, "iwantovisit":"O0PSwantf1agnow1"
生成一个串来和输入进行异或
然后对比数据可以发现,输入加密后存在了这里v181这里都是同样的8个一组
记录下来,后面会用到
在这往后也是一堆异或操作
往后找,直到这里
看看src,dump下来
再往后是一些base64加密
然后到这里
在汇编界面运行到这里
可以得到输入的最后加密结果
把他base64解密一下,得到的和之前记录的src一样,印证了中间一大串都是base64
那我们用最初记录下来的8位一组的加密结果与src异或
然后我们换个输入,同样的做法也会得到相同的值,说明这就是密钥
用这个密钥去异或最后的加密结果,还原出异或前的值
然后这个值再异或0x33
就得到一串只要解最开始的前两位-1然后两位不变,再两位+1,最后两位+2就是正确输入的数据了
我们用正确的密文解一下
写个脚本解一下
exp
1 | enc = [0x65,0x6b,0x61,0x67,0x7c,0x37,0x67,0x34,0x33,0x37,0x30,0x62,0x34,0x2e,0x36,0x68,0x2f,0x31,0x2d,0x34,0x64,0x67,0x33,0x2f,0x38,0x61,0x63,0x30,0x2e,0x32,0x34,0x35,0x61,0x36,0x35,0x66,0x3a,0x62,0x3b,0x34,0x31,0x7c,0x45,0x45,0x46,0x46,0x47,0x47,0x44,0x44,0x45,0x45,0x46,0x46,0x47,0x47,0x44,0x44,0x45,0x45,0x46,0x46,0x47,0x47,0x44,0x44,0x45,0x45,0x46,0x46,0x47,0x47,0x44,0x44,0x45,0x45,0x46,0x46,0x47,0x47,0x44,0x44,0x45,0x45,0x46,0x46,0x47,0x47,0x44,0x44,0x45,0x45,0x46,0x46,0x47,0x47,0x44,0x44,0x45,0x45,0x46,0x46,0x47,0x47] |
whereThel1b
以为是cython逆向,硬看so,脑子直接炸
后来转念一想,运行脚本看看呢
输入任意三个字符trytry都返回4个数字
猜测跟base有关或者类似
考虑每次去爆破三个字符,然后补齐剩下的,调用trytry得到返回值去和密文比较
注意so的调用必须是linux 下python 3.10
exp
1 | import whereThel1b |
gdb_debug
种子是固定的
考虑直接动调,拿异或因子
第一个断点,拿到v20异或因子,只取低两位0xD9
第二个断点
然后转到汇编,一直F8运行至这里
点ptr获得indx值
第三个断点
然后转到汇编,在rand()
处再下个断点,同样取低两位 0xDE
最后的数据是静态的byte数组,点进去就行了
exp
1 | key = [0xBF, 0xD7, 0x2E, 0xDA, 0xEE, 0xA8, 0x1A, 0x10, 0x83, 0x73, 0xAC, 0xF1, 0x06, 0xBE, 0xAD, 0x88, 0x04, 0xD7, 0x12, 0xFE, 0xB5, 0xE2, 0x61, 0xB7, 0x3D, 0x07, 0x4A, 0xE8, 0x96, 0xA2, 0x9D, 0x4D, 0xBC, 0x81, 0x8C, 0xE9, 0x88, 0x78] |