Easyxtea

Easyxtea

https://hgame.vidar.club/games/8/challenges?challenge=99

分析pseudocode,
Easyxtea-1
非常简洁清晰的流程,
读入用户32字节字符串,存入Buf2,
将xmmword_140003270的数据读入Buf1,
四组tea家族加密,

点击v12,v13,v14发现这是在栈上连续的32字节空间,
Easyxtea-2
也就是plain存到Buf2的时候事实上后24位是注入到v12,v13,v14的

Buf2 = [0~7]
v12 = [8~15]
v13 = [16~23]
v14 = [24~31]
这就弄清了每组加密是在加密哪段plain,

点进去看一下是什么茶
Easyxtea-3
标准的x茶,
数一下魔数的出现次数为16次,do-while循环两次,即16*2=32轮

接下来就是获取key和cipher,
pseudocode里有xmmword_1400032XX的数据,点开看看
Easyxtea-4
获得key和cipher,
cipher为两组128bit,对应四组x茶加密,

注意这里有一个坑点,在组合加密后plain的时候,是先xmmword_140003290,后xmmword_140003280
也就是倒过来,90地址段的是cipher前16字节,80段是后16字节,

编写dec

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
#include <bits/stdc++.h>
using namespace std;

uint32_t cipher[4][2] = {
{0x9F249FB2, 0x917A3218},
{0x8CA57C30, 0xD07FB03B},
{0xE9F399AA, 0x7BF711F4},
{0x6AA17CFB, 0x31CADE93}
};

uint32_t key[4] = {1,2,3,4};

void decrypt(uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], delta=0x9E3779B9, sum=0xC6EF3720;
for (uint32_t i=0; i<32; i++) {
v1 -= (((v0<<4) ^ (v0>>5)) + v0) ^ (sum + k[(sum>>11) & 3]);
sum -= delta;
v0 -= (((v1<<4) ^ (v1>>5)) + v1) ^ (sum + k[sum & 3]);
}
v[0]=v0; v[1]=v1;
}

int main() {
for (int i = 0; i < 4; i++) {
decrypt(cipher[i], key);
cout.write(reinterpret_cast<char *>(&cipher[i][0]), sizeof(cipher[i][0]));
cout.write(reinterpret_cast<char *>(&cipher[i][1]), sizeof(cipher[i][1]));
}
return 0;
}

Easyxtea-5