Reverse
Rustdroid
Java层智能看到调用了Native层的Check
看看SO,是个Rust,大体看一下是 RC4
这里先判断flag长度是否为43,和是否以WMCTF{}
包裹
这里是rc4的S盒,可以动调或者直接模拟拿到S盒,fun@eZ
是RC4的key
这里是单字节位移加密,同时还有给RC4加了一个异或
异或的值
单字节位移加密逻辑如下
1 2 3 4 5 6 7 8 9 10 def ROR (value, shift, bits=8 ): return ((value >> shift) | (value << (bits - shift))) & ((1 << bits) - 1 ) def rotate_enc (x ): x = ROR(x, 1 ) ^ 0xef x = ROR(x, 2 ) ^ 0xbe x = ROR(x, 3 ) ^ 0xad x = ROR(x, 4 ) ^ 0xde x = ROR(x, 5 ) return x
这里再记录一下SO的调试方法
先 adb 连接一下模拟器
需要先把ida服务push到模拟器
1 adb push D:\CTF\RE\IDA_Pro_7.7\dbgsrv\android_server64(ida安装路径) /data/local/tmp/android_server64
然后连接
1 2 3 4 5 adb shell su cd /data/tmp/local chmod 777 android_server64 ./android_server64
再开个命令行转发一下端口
1 adb forward tcp:23946 tcp:23946
选择Remote Android debugger
然后Debugger里选择Attach to process,找到对应的包名进行附加
exp
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 from struct import packdef ROR (value, shift, bits=8 ): return ((value >> shift) | (value << (bits - shift))) & ((1 << bits) - 1 ) def rotate_enc (x ): x = ROR(x, 1 ) ^ 0xef x = ROR(x, 2 ) ^ 0xbe x = ROR(x, 3 ) ^ 0xad x = ROR(x, 4 ) ^ 0xde x = ROR(x, 5 ) return x data = [0x4E4FCE594215BA1F , 0xC745BAE69BFD994 , 0x87081E9C7F8AFCC0 , 0x2BB08F87F5646BF5 ] enc = [] for i in data: enc += list (pack("<Q" , i)) enc += list (pack("<I" ,0x29FF53E2 )) key = [0x66 , 0x75 , 0x6E , 0x40 , 0x65 , 0x5A ] xor_table = [0x77 , 0x88 , 0x99 , 0x66 ] def rc4 (key, data ): key_length = len (key) s = list (range (256 )) j = 0 for i in range (256 ): j = (j + s[i] + key[i % key_length]) % 256 s[i], s[j] = s[j], s[i] res = [] i = j = 0 for index, val in enumerate (data): i = (i + 1 ) % 256 j = (j + s[i]) % 256 s[i], s[j] = s[j], s[i] k = s[(s[i] + s[j]) % 256 ] res.append(val ^ k ^ xor_table[index % 4 ]) return res decrypted_data = rc4(key, enc) flag = "WMCTF{" for i in range (36 ): for j in range (30 , 128 ): if rotate_enc(j) == decrypted_data[i]: flag += chr (j) break flag += "}" print (flag)
re1
先Jadx看看,应该是有Hook
看看so
这里对几个函数memcmp、strlen、printf、strftime、scanf、fgetws
进行了Hook
checkYourFlag是假逻辑
在JNI_Onload可以找到真正的加密逻辑
真正的在sub_F430
进入sub_F430就可以动调跟踪被Hook的函数
strlen对输入进行了异或
printf、scanf、strftime、fgetws实现了xtea
密文
exp
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 #include <stdio.h> #include <stdint.h> void decipher (unsigned int num_rounds, uint32_t v[2 ], uint32_t const key[4 ]) { unsigned int i; uint32_t v0 = v[0 ], v1 = v[1 ], delta = 0xfa11010d , sum = delta * num_rounds; for (i = 0 ; i < num_rounds; i++) { v1 -= (((v0 << 6 ) ^ (v0 >> 6 )) + v0) ^ (sum + key[(unsigned char )sum >> 6 ]); sum -= delta; v0 -= (((v1 << 6 ) ^ (v1 >> 6 )) + v1) ^ (sum + key[sum & 3 ]); } v[0 ] = v0; v[1 ] = v1; } int main () { uint32_t enc[] = { 0xEFC05FD2 , 0x9378625E , 0x841F41A0 , 0x6D05F4A , 0xDC898F9A ,0x21AA7CFC ,0x4229FB0B ,0x31E52B8B }; uint32_t key[4 ] = { 0xffffffff , 0xaaaaaaaa , 0x11111111 , 0x11111111 }; for (int i=0 ; i<8 ; i+=2 ){ decipher (66 , &enc[i], key); } for (int i = 0 ; i < 32 ; i++) { printf ("%c" , (*((char *)enc + i) ^ 0x5A ^ i)); } } #WMCTF{b86d69bbeedeccb9257782534}