美团CTF RE small

2022 美团 MT-CTF

Small

借鉴:[原创]2022MT-CTF Re-茶余饭后-看雪论坛-安全社区|安全招聘|bbs.pediy.com

在做题的时候看到是ELF文件,直接尝试在Ubuntu上面运行,但是提示段错误。然后用IDA64打开,一直报错。想怎么修复ELF头,让他能直接运行,也有大佬提示试试看是不是shellcode,但是都失败了,看到了wp人都傻了。

首先用IDA64, 二进制模式打开

然后在0x68处按C反汇编,

image-20220920194825703

经典的三个数两次异或运算,左移4,右移5

看cutter的反编译更清楚,可以得知这是一个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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include <stdint.h>

int64_t entry0 (int64_t arg_10h, int64_t arg4, int64_t arg1) {
rcx = arg4;
rdi = arg1;
rsi = arg_10h;
label_0:
ebx = 0;
edx = ebx;
eax = 0x3e0002;
eax = *(rsi);
rsi += 4;
tmp_0 = eax;
eax = ebp;
ebp = tmp_0;
eax = entry0;
*(rax) += al;
*(rax) += al;
*(rax) += al;
*(rax) += al;
*(rax) += al;
if (*(rsp) != 2) {
goto label_1;
}
eax = *(rsi);
rsi += 4;
tmp_1 = eax;
eax = edi;
edi = tmp_1;
do {
ecx = edi;
eax = edi;
ebx += 0x67452301; //DELTA == 0x67452301
ecx <<= 4; //左移4
ecx++;
eax >>= 5; //右移5
eax += 0x23;
ecx ^= eax; //异或
eax = edi;
eax += ebx;
ecx ^= eax; //异或
ebp += ecx;
ecx = ebp;
ecx >>= 5; //右移5
ecx += 0x67;
eax = ebp;
eax <<= 4; //左移4
eax += 0x45;
ecx ^= eax;
eax = ebp;
eax += ebx;
ecx ^= eax;
edi += ecx;
edx++;
} while (edx < 0x23); //加密轮数为0x23次
*((rsi - 8)) = ebp;
*((rsi - 4)) = edi;
ecx = arg_10h;
ecx += 0x20;
if (esi < ecx) {
goto label_0;
}
tmp_2 = rax;
rax = rsi;
rsi = tmp_2;
esi = 0x20;
do {
cl = *(rax);
if (*((esi + 0x100f7)) != cl) { //加密结束后与预先保存的密文进行倒序对比
goto label_1;
}
esi--;
rax--;
} while (esi != 0);
edi = 1;
esi = 0x100f3;
eax = 1;
dx = 4;
rax = syscall_80h (rdi, rsi, rdx, r10, r8, r9);
label_1:
eax = 0x3c;
edi = esi;
rax = syscall_80h (rdi, rsi, rdx, r10, r8, r9);
__asm ("outsd dx, dword [esi]");
__asm ("outsd dx, dword [rsi]");
if (esi overflow 0) {
fp_status = fp_compare(fp_stack[0], fp_stack[0]);
fp_stack++;
edi -= ecx;
}
fp_stack[0] *= *((rbp + rdx*8 - 0x62));
__asm ("insd dword [rdi], dx");
__asm ("out 0x4e, eax");
return void (*0x10180)() ();
}

直接定位到0x100f7,可以找到密文就是在0x100f7~0x100f7+0x20之间

image-20220920214933839

解密脚本

1
2
3
4
5
6
7
8
enc=list(bytes.fromhex('437108ded21bf9c4dcdaf6da4cd59e6de74eeb7504dc1d5dd90f1b51fb88dc51'))
for i in range(0,len(enc),4):
num=0
for j in range(4):
num|=(enc[i+j]<<(8*j))
print(hex(num),end=',')

#0xde087143,0xc4f91bd2,0xdaf6dadc,0x6d9ed54c,0x75eb4ee7,0x5d1ddc04,0x511b0fd9,0x51dc88fb
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
#include<iostream>
#define ut32 unsigned int
#define delta 0x67452301

void Tea_Decrypt(ut32* enc) {
unsigned int sum = 0x67452301 * 0x23;//0x1e73c923;
ut32 v0 = enc[0];
ut32 v1 = enc[1];
for (int i = 0; i < 0x23; i++) {
v1 -= ((v0 << 4) + 0x45) ^ (v0 + sum) ^ ((v0 >> 5) + 0x67);
v0 -= ((v1 << 4) + 1) ^ (v1 + sum) ^ ((v1 >> 5) + 0x23);
sum -= 0x67452301;
}
enc[0] = v0;
enc[1] = v1;
}

void Tea_Encrypt(ut32* src) {
ut32 sum = 0;
ut32 v0 = src[0];
ut32 v1 = src[1];
for (int i = 0; i < 0x23; i++) {
sum += 0x67452301;
v0 += ((v1 << 4) +1) ^ (v1 + sum) ^ ((v1 >> 5) + 0x23);
v1 += ((v0 << 4) + 0x45) ^ (v0 + sum) ^ ((v0 >> 5) + 0x67);
}
printf("%08x\n", sum);
src[0] = v0;
src[1] = v1;
}
int main() {
ut32 enc[8] = { 0xde087143,0xc4f91bd2,0xdaf6dadc,0x6d9ed54c,0x75eb4ee7,0x5d1ddc04,0x511b0fd9,0x51dc88fb };
for (int i = 0; i < 8; i += 2) {
Tea_Decrypt(enc+i);
}

for (int i = 0; i < 32; i++) {
printf("%c",*((unsigned char*)enc+i));
}
//327a6c4304ad5938eaf0efb6cc3e53dc
return 0;
}

美团CTF RE small
http://example.com/2022/10/09/2022美团CTF-RE-small/
Author
Eutop1a
Posted on
October 9, 2022
Licensed under