RE

snack

pyc解包,pycdc反编译,得到一个rc4加密,复制加密过程直接解密即可

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
def pl(a, b=None):
if all(0 <= x <= 255 for x in a):
result = ''.join(chr(a[i]) for i in range(len(a)))
else:
result = (''.join([long_to_bytes(a[i]).decode() for i in range(len(a)-1,-1,-1)]))[::-1]

if b is None:
print(result)
else:
if result.startswith(b):
print(result)
elif '{' in result and '}' in result:
print(f"{b}{result}")
else:
print(f"{b}{{{result}}}")
def initialize(key):
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]
return S

def generate_key_stream(S, length):
i = 0
j = 0
key_stream = []
for _ in range(length):
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i],S[j] = S[j],S[i]
key_stream.append(S[(S[i] + S[j]) % 256])
return key_stream


def decrypt(data, key):
S = initialize(key)
key_stream = generate_key_stream(S, len(data))
decrypted_data = [i^ data[i] ^ key_stream[i] for i in range(len(data))]
return decrypted_data

data = [
101,
97,
39,
125,
218,
172,
205,
3,
235,
195,
72,
125,
89,
130,
103,
213,
120,
227,
193,
67,
174,
71,
162,
248,
244,
12,
238,
92,
160,
203,
185,
155]
xor_key = 'V3rY_v3Ry_Ez'
key = []
for i in range(len(xor_key)):
key.append(ord(xor_key[i]))
pl(decrypt(data, key))
# flag{KMLTz3lT_MePUDa7A_P5LpzCBT}

HardSignin

先去一个upx

有4个tls,里面有花和反调,去花杀反调,似乎是用随机数生成之后加密用的参数,同时对main解密

image-20240706182721253

image-20240706195234707

image-20240706195330050

在tls2里面下断点到这里已经生成的数据

main里面3个步骤

image-20240706182810516

base64,rc4和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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include<iostream>
#include<stdlib.h>
#include<Windows.h>
#include<string.h>
BYTE S[256] = {};

void decTEA(unsigned* target, unsigned* key) {
unsigned int sum = 0;
unsigned int v5;
unsigned int v6;

for (int i = 0; i < 16; i += 2)
{
v6 = target[i];
v5 = target[i + 1];
sum = 0 - 0x61C88647 * 0x64;
for (int j = 0; j < 0x64; ++j)
{
v5 -= (key[(sum >> 11) & 3] + sum) ^ (v6 + ((v6 >> 5) ^ (16 * v6)));
sum += 0x61C88647;
v6 -= (key[sum & 3] + sum) ^ (v5 + ((v5 >> 5) ^ (16 * v5)));


}
target[i] = v6;
target[i + 1] = v5;
}
}

//void __cdecl sub_A71A10(unsigned int round, DWORD* target, DWORD* key)
//{
// unsigned int j; // [esp+4Ch] [ebp-18h]
// unsigned int sum; // [esp+54h] [ebp-10h]
// unsigned int v5; // [esp+58h] [ebp-Ch]
// unsigned int v6; // [esp+5Ch] [ebp-8h]
// int i; // [esp+60h] [ebp-4h]
//
// for (i = 0; i < 16; i += 2)
// {
// v6 = target[i];
// v5 = target[i + 1];
// sum = 0;
// for (j = 0; j < round; ++j)
// {
// v6 += (key[sum & 3] + sum) ^ (v5 + ((v5 >> 5) ^ (16 * v5)));
// sum -= 0x61C88647;
// v5 += (key[(sum >> 11) & 3] + sum) ^ (v6 + ((v6 >> 5) ^ (16 * v6)));
// }
// target[i] = v6;
// target[i + 1] = v5;
// }
//}
void __cdecl swap(BYTE* a1, BYTE* a2)
{
char v2; // [esp+4Fh] [ebp-1h]

v2 = *a1;
*a1 = *a2;
*a2 = v2;
}
void __cdecl Sini(BYTE* a1, int len)
{
int k; // [esp+4Ch] [ebp-114h]
int v3; // [esp+50h] [ebp-110h]
int j; // [esp+54h] [ebp-10Ch]
char v5[256]; // [esp+58h] [ebp-108h] BYREF
int i; // [esp+158h] [ebp-8h]

for (i = 0; i < 256; ++i)
S[i] = i;
memset(v5, 0, sizeof(v5));
for (j = 0; j < 256; ++j)
v5[j] = a1[j % len];
v3 = 0;
for (k = 0; k < 256; ++k)
{
v3 = ((unsigned __int8)v5[k] + v3 + (unsigned __int8)S[k]) % 256;
swap(&S[k], &S[v3]);
}
}
void __cdecl decrc4(BYTE* target, int len, unsigned char* a3)
{
int i; // [esp+4Ch] [ebp-14h]
int v6; // [esp+54h] [ebp-Ch]
int v7; // [esp+58h] [ebp-8h]

v7 = 0;
v6 = 0;
Sini(a3, 16);
for (i = 0; i < len; ++i)
{
v7 = (v7 + 1) % 256;
v6 = (v6 + (unsigned __int8)S[v7]) % 256;
swap(&S[v7], &S[v6]);
target[i] ^= S[((unsigned __int8)S[v6] + (unsigned __int8)S[v7]) % 256];
}
}


int main(void) {
unsigned char last[64] = {
0x59, 0x1B, 0xFD, 0xB4, 0x6B, 0xB8, 0xBE, 0xD9, 0xB3, 0xD3, 0x77, 0xD6, 0xF0, 0x65, 0x5F, 0x18,
0xA0, 0x9D, 0x3A, 0x53, 0x6D, 0x4A, 0x7B, 0x26, 0x74, 0x3A, 0x9C, 0x4E, 0x20, 0x43, 0x19, 0xD8,
0x72, 0xED, 0x95, 0xB5, 0x9C, 0x05, 0x22, 0x56, 0xCB, 0x7A, 0x11, 0x91, 0x9F, 0x7A, 0xBC, 0x0C,
0x4A, 0x69, 0x6D, 0xCE, 0x3D, 0xB4, 0xAB, 0x29, 0x61, 0xFA, 0x62, 0x32, 0xB4, 0xEC, 0x4C, 0xB6
};
unsigned int key[4] = {
0x0CAA5BDD, 0xD6846924, 0x51041EB8, 0x8B2AAB06
};
decTEA((unsigned*)last, key);
unsigned char ikey[16] = {
0x76, 0x89, 0x33, 0x49, 0x19, 0x13, 0xC3, 0xC7, 0xAD, 0xD8, 0xE4, 0x68, 0xFC, 0x48, 0x04, 0xBC
};
decrc4(last, 64, ikey);
for (int i = 0; i < 64; i++)
{
std::cout << (unsigned char)last[i];
}
}
// C+vFCnHRGPghbmyQMXvFMRNd7fNCG8jcU+jcbnjRJTj2GTCOGUvgtOS0CTge7fNs

对着码表直接解密

4yZRiNP8LoK/GSA5ElWkUjXtJCz7bMYcuFfpm6+hV0rxeHIdwv32QOTnqg1BDsa9

1
flag{C0ngr@tulat1on!Y0u_Re_suCces3fu1Ly_Signln!}

bedTEA

观察main逻辑,先用一个奇怪算法生成了key,然后执行XTEA加密,一共三次,这里没看懂奇怪算法是什么,但是好像跟输入无关,于是尝试动调,出来后发现是斐波那契数列,用这个写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
#include<Windows.h>
#include<iostream>
void may_ini(DWORD* input, DWORD* key_array)
{
int key_index; // 对应于原代码中的 v1
int key_end; // 对应于原代码中的 v3
int temp_key_index; // 对应于原代码中的 v4
int temp1, temp2, temp3, temp4, temp5; // 对应于原代码中的 v5, v6, v7, v8, v9
int temp6; // 对应于原代码中的 v10
int temp7; // 对应于原代码中的 v11
int key_value; // 对应于原代码中的 v12
unsigned int input_second; // 对应于原代码中的 v13
int delta; // 对应于原代码中的 v14
unsigned int input_first; // 对应于原代码中的 v15
int key = 3;

input_second = input[1];
delta = 0x987E55D0;
input_first = *input;
do
{
input_second -= (delta + input_first) ^ (key_array[3] + (input_first >> 4)) ^ (key_array[2] + 32 * input_first);
input_first -= (delta + input_second) ^ (key_array[1] + (input_second >> 4)) ^ (key_array[0] + 32 * input_second);

delta += 0x61CBB648;
} while (delta != 0);
*input = input_first;
input[1] = input_second;
}

int main(void) {
BYTE last[] = { 211, 109, 186, 193, 54, 101, 42, 137, 120, 145, 245, 49, 250, 190, 194, 49, 144, 12, 68, 67, 212, 174, 66, 69 , 0};
BYTE data[24] = {
0xF7, 0xA1, 0x04, 0xD8, 0xD3, 0xF7, 0x2F, 0x25, 0x06, 0x91, 0xF9, 0xEC, 0xDD, 0x03, 0xC8, 0xA9,
0xE1, 0x84, 0xF0, 0xFE, 0xAF, 0x4E, 0xDF, 0xD1
};
DWORD rkey[4] = {
0x00000003, 0x00000005, 0x00000008, 0x0000000D
};
may_ini((DWORD*)last, rkey);
DWORD rkey2[4] = {
0x00000015, 0x00000022, 0x00000037, 0x00000059
};
may_ini((DWORD*)last + 2, rkey2);
DWORD rkey3[4] = {
0x00000090, 0x000000E9, 0x00000179, 0x00000262
};
may_ini((DWORD*)last + 4, rkey3);
std::cout << (char*)last;
}

tea流程之后后面好像xor了好多东西,把每个地址都改名

image-20240707151103500

然后对最后检查的地址下读写断点,发现第一次写入时是倒序传入

然后异或了0x33

那么把最后的值倒序然后异或,然后解密tea即可得到flag

1
flag{y0u_reallyl1ke_te@}