0x01 TBXO

只会看了这一道,应该也只会这一道了。

5eabd65659bf0b96f62a129e0a95673

打开后f5,发现全是这种无意义的也不是函数的东西,感觉是经过防止反汇编的处理,无奈只能看汇编代码。

shift+f12找有用的字符串,发现有一个welcome 和wrong right等字眼的字符,点进去查找引用看看,能很快定位到main函数,当然是没法f5的,动调一步一步调试看会去哪里

image-20240218134920902

发现这个是scanf函数,要输入flag,不知道flag是多少位,发现输入错误后程序会直接中断。当时在调试的时候无意间发现了一些类似加密函数的汇编代码,因为就在这个scanf函数下面,也是多看了几眼,然后发现是一个tea加密,不过f5后的代码是有问题的,不够全面,而且有很多差错。

image-20240218135144035

如图,首先先不谈这些v1,v4,v2的是什么东西,关是这个a1 什么什么的就反汇编得很糟糕了,点进去这个unk_CC3004,发现是一个长度40char的数据,盲猜是enc密文,再动调试一下输入长度40 的flag,发现能调试到这一个函数了,直接看汇编。

image-20240218135524860

不难发现这个v1 就是 (a - 1),v4就是 a,然后edi是存储sum 的 寄存器,每次循环加上 -0x61C88647,动调发现循环0x20轮,很典型的tea加密,就是多异或了一次0x33,这些信息看f5伪代码肯定是看不出来的,所以还是建议看汇编代码,比较准确。

解密的逻辑

1
2
3
4
5
6
7
8
9
10
__int32 key1 = 0x67626463, key2 = 0x696D616E, key3 = 0x79645F65, key4 = 0x6B696C69;
__int32 delta = -0x61c88647;
void decrypt(unsigned __int32 &esi,unsigned __int32 &eax){
__int32 sum = delta *32;
for(int i = 0;i < 32; i++){
eax -= (esi + sum) ^ (key3 + (esi << 4)) ^ (key4 + (esi >> 5)) ^ 0x33;
esi -= (eax + sum) ^ (key1 + (eax << 4)) ^ (key2 + (eax >> 5)) ^ 0x33;
sum -= delta;
}
}

完整脚本,只要把40位密文分成10份然后两两加密就好了

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
#include<iostream>
__int32 key1 = 0x67626463, key2 = 0x696D616E, key3 = 0x79645F65, key4 = 0x6B696C69;
__int32 delta = -0x61c88647;
unsigned __int32 enc[40] = {0x10, 0x30, 0x36, 0x31, 0x23, 0x86, 0x93, 0xAD, 0xC5, 0xD4,
0x92, 0x84, 0x66, 0xE3, 0x67, 0x75, 0x6B, 0x69, 0x86, 0xC7,
0x31, 0x2E, 0x09, 0xA0, 0x33, 0x57, 0x69, 0xDB, 0x93, 0xA8,
0x13, 0xDD, 0x3E, 0xA5, 0xD8, 0x88, 0x37, 0x54, 0x84, 0x7E};
unsigned __int32 enc2[10] = {0};
//解密逻辑
void decrypt(unsigned __int32 &esi,unsigned __int32 &eax){
__int32 sum = delta *32;
for(int i = 0;i < 32; i++){
eax -= (esi + sum) ^ (key3 + (esi << 4)) ^ (key4 + (esi >> 5)) ^ 0x33;
esi -= (eax + sum) ^ (key1 + (eax << 4)) ^ (key2 + (eax >> 5)) ^ 0x33;
sum -= delta;
}
}
//合并密文
void trans(){
for(int i = 0;i < 10; i++){
enc2[i] = (enc[4 * i]) | (enc[4 * i + 1] << 8) | (enc[4 * i + 2] << 16) | (enc[4 * i + 3] << 24);
}
}
//拆分密文
void trans2(){
for(int i = 0;i < 10; i++){
enc[4 * i] = enc2[i] & 0xff;
enc[4 * i + 1] = (enc2[i] >> 8) & 0xff;
enc[4 * i + 2] = (enc2[i] >> 16) & 0xff;
enc[4 * i + 3] = (enc2[i] >> 24) & 0xff;
}
}
int main(){
trans();
int i = 0;
while(i < 10){
decrypt(enc2[i],enc2[i+1]);
i = i + 2;
}
trans2();
for(int i = 0;i < 40;i ++){
printf("%c",enc[i]);
}
return 0;
}
//VNCTF{Box_obfuscation_and_you_ar_socool}