极客赛 have_a_tea

先拖出来查壳,发现是elf文件,ida64打开,发现文件内容很少,应该是被加密了

用wsl2远程调试

被奇怪的反调试拦截

restart

查看函数结构,发现start函数有跳转

跟进jmp 跳转

继续跟进libc start函数

弹出处下断点

被fork子进程拦截?

直接C+n越过fork创建

找到关键代码

先来学习一下tea加密解密,我还不会这个方式

Google上出来的:加密使用的数据为2个32位无符号整数,密钥为4个32位无符号整数即密钥长度为128位。TEA、XTEA、XXTEA加密解密算法 - 简书 (jianshu.com) (4条消息) TEA系列加解密算法详解_Markus-CSDN博客_tea解密

简单来讲,就是对密钥和数据进行加法和位移多次循环把数据和密钥打散混乱。逆向的话只需要反着来就行了。这个算法的特点在于他会以32bit为运算单位

找到加密部分

出现了一些奇怪的问题,比如encrypt内的函数全部带上了(int_64) 的强制转换,emmm,没有截到图,有点难受。

关键加密部分

看一下代码逻辑

因为加密算法是以32bit运行的,所以我们用dword 双字来提取data和key

[0x5F797274, 0x64726168, //这前面两个是用来获取后面亦或的初始值data

0x65766967, 0x756F795F,0x7075635F,0x6165745F]

DATA

[0xC9FA3B95, 0x7CFD0735, 0x958C7C9F, 0xC143B59E, 0x61741E89, 0xF47DCDC4, 0xD6E2A1F2, 0x6A38E9AD, 0xC2C16FEB, 0x8C0EE999, 0x6520C6A0]

总体就是先取两个值进行亦或,然后再tea加密,然后再通过循环把数据传回去,当初值接出来之后要用解出来的值进行下一步解密

写脚本

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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <stdio.h>  
#include <stdint.h>
uint32_t data1 = 0x5F797274;
uint32_t data2 = 0x64726168;
//加密函数
void encrypt (uint32_t* v, uint32_t* k)
{
uint32_t v0=v[0], v1=v[1], sum=0, i;/* set up */
data1 ^= v0;
data2 ^= v1;
v0 = data1;
v1 = data2;
uint32_t delta=0x9E3779B9; /* a key schedule constant */
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache(缓存) key */
for (i=0; i < 32; i++) { /* basic cycle start */
sum += delta;
v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);


} /* end cycle */
data1 = v0;
data2 = v1;

}
//解密函数

void decrypt(uint32_t * v, uint32_t * k) {
uint32_t delta = 0x9E3779B9; /* a key schedule constant */
uint32_t v0 = v[0], v1 = v[1], sum = (delta * 32) & 0xffffffff, i; /* set up */
uint32_t k0 = k[0], k1 = k[1], k2 = k[2], k3 = k[3]; /* cache key */
for (i = 0; i < 32; i++) { /* basic cycle start */
v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
sum -= delta;
} /* end cycle */
v0=v0^data1;
v1=v1^data2;
v[0] = v0;v[1] = v1;
}

int main()
{
uint32_t array[] = { 0xC9FA3B95, 0x7CFD0735, 0x958C7C9F, 0xC143B59E, 0x61741E89,
0xF47DCDC4, 0xD6E2A1F2, 0x6A38E9AD, 0xC2C16FEB, 0x8C0EE999, 0x4A20156D };
uint32_t key[4] = { 0x65766967, 0x756F795F, 0x7075635F, 0x6165745F };
int i = 0;
for (i = 0; i < 10; i += 2)
{
uint32_t temp[2];
temp[0] = array[i];
temp[1] = array[i + 1];
decrypt(temp, key);
printf("%c%c%c%c%c%c%c%c", *((char*)&temp[0] + 0), *((char*)&temp[0] + 1), *
((char*)&temp[0] + 2), *((char*)&temp[0] + 3), *((char*)&temp[1] + 0), *
((char*)&temp[1] + 1), *((char*)&temp[1] + 2), *((char*)&temp[1] + 3));
//下方更新
encrypt(temp, key);
}

return 0;
}

// v为要加密的数据是两个32位无符号整数
// k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位

拖了好久啊www

真累啊