2024春秋杯冬季赛-第一天

rev

easyre

使用固定的值做随机数种子,但不能在调试环境中做,需要先运行程序再附加,再提取数据。

koOh

rc4 加密,但是减法

提取出 key

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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173

int __cdecl encrypt(unsigned char* input, unsigned char* output, int inputLen, char* key, int keylen)
{
unsigned int result; // eax
unsigned char v6; // [esp+DFh] [ebp-135h]
unsigned int i; // [esp+E8h] [ebp-12Ch]
unsigned int v8; // [esp+F4h] [ebp-120h]
unsigned int v9; // [esp+100h] [ebp-114h]
unsigned char v10[260]; // [esp+10Ch] [ebp-108h] BYREF


unsigned char v4; // [esp+D3h] [ebp-29h]
unsigned int j; // [esp+DCh] [ebp-20h]
unsigned int v7; // [esp+F4h] [ebp-8h]

v7 = 0;
for (i = 0; i < 256; ++i)
{
v10[i] = i;
result = i + 1;
}
for (j = 0; j < 256; ++j)
{
v7 = ((unsigned __int8)key[j % keylen] + v7 + (unsigned __int8)v10[j]) % 256;
v4 = v10[j];
v10[j] = v10[v7];
v10[v7] = v4;
result = j + 1;
}


v9 = 0;
v8 = 0;
for (i = 0; ; ++i)
{
result = i;
if (i >= inputLen)
break;
v9 = (v9 + 1) % 256;
v8 = (v8 + (unsigned __int8)v10[v9]) % 256;
v6 = v10[v9];
v10[v9] = v10[v8];
v10[v8] = v6;
output[i] = input[i] - v10[(unsigned __int8)(v10[v8] + v10[v9])];
printf("%02x", v10[(unsigned __int8)(v10[v8] + v10[v9])]);

}
return result;
}



int __cdecl decrypt(unsigned char* input, unsigned char* output, int inputLen, char* key, int keylen)
{
int result; // eax
char v6; // [esp+DFh] [ebp-135h]
int i; // [esp+E8h] [ebp-12Ch]
int v8; // [esp+F4h] [ebp-120h]
int v9; // [esp+100h] [ebp-114h]
unsigned char v10[260]; // [esp+10Ch] [ebp-108h] BYREF


char v4; // [esp+D3h] [ebp-29h]
int j; // [esp+DCh] [ebp-20h]
int v7; // [esp+F4h] [ebp-8h]

v7 = 0;
for (i = 0; i < 256; ++i)
{
v10[i] = i;
result = i + 1;
}
for (j = 0; j < 256; ++j)
{
v7 = ((unsigned __int8)key[j % keylen] + v7 + (unsigned __int8)v10[j]) % 256;
v4 = v10[j];
v10[j] = v10[v7];
v10[v7] = v4;
result = j + 1;
}


v9 = 0;
v8 = 0;
for (i = 0; ; ++i)
{
result = i;
if (i >= inputLen)
break;
v9 = (v9 + 1) % 256;
v8 = (v8 + (unsigned __int8)v10[v9]) % 256;
v6 = v10[v9];
v10[v9] = v10[v8];
v10[v8] = v6;
output[i] = input[i] + v10[(unsigned __int8)(v10[v8] + v10[v9])];
//printf("%02x", v10[(unsigned __int8)(v10[v8] + v10[v9])]);
printf("%c", output[i]);

}
return result;
}


int __cdecl sub_402B60(unsigned char* a1, signed int Size)
{
char v3; // [esp+0h] [ebp-124h]
signed int i; // [esp+D0h] [ebp-54h]
unsigned char* v5; // [esp+DCh] [ebp-48h]
unsigned char v6[43]; // [esp+E8h] [ebp-3Ch] BYREF
int key_len; // [esp+11Ch] [ebp-8h]
char key[] = { "DDDDAAAASSSS" };
key_len = strlen(key);
v6[0] = 24;
v6[1] = -100;
v6[2] = 71;
v6[3] = 61;
v6[4] = 59;
v6[5] = -31;
v6[6] = 41;
v6[7] = 39;
v6[8] = -97;
v6[9] = 52;
v6[10] = -125;
v6[11] = -43;
v6[12] = -19;
v6[13] = -75;
v6[14] = 'n';
v6[15] = 'Y';
v6[16] = 127;
v6[17] = -34;
v6[18] = 71;
v6[19] = -41;
v6[20] = 101;
v6[21] = 63;
v6[22] = 122;
v6[23] = 51;
v6[24] = 91;
v6[25] = 100;
v6[26] = -74;
v6[27] = -6;
v6[28] = -108;
v6[29] = 85;
v6[30] = -121;
v6[31] = 66;
v6[32] = 32;
v6[33] = 6;
v6[34] = 12;
v6[35] = 105;
v6[36] = -2;
v6[37] = 114;
v6[38] = -87;
v6[39] = -28;
v6[40] = -47;
v6[41] = 124;

for (i = 0; i < Size; ++i)
{
printf("%02x", v6[i]);
}
printf("\n\n\n");
v5 = (unsigned char*)malloc(Size);
if (!v5)
return -1;
encrypt(a1, v5, Size, key, key_len);
//decrypt(v6, v5, Size, key, key_len);

for (i = 0; i < Size; ++i)
{
if (v6[i] != (unsigned __int8)v5[i])
return 0;
}
return Size;
}

做反运算,得到flag

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18



key = bytes.fromhex("4ed01a2a40820c119902b5914578f3ddb383e65ed3f5e8fa07cdb03a99e4aa20192d28cf63c7b84e6101")
data = bytes.fromhex("189c473d3be129279f3483d5edb56e597fde47d7653f7a335b64b6fa9455874220060c69fe72a9e4d17c")


for i in range(len(data)):
if key[i] > data[i]:
res = data[i] + key[i]
else:
res = (data[i] - 0x100)+ key[i]

res = res & 0xff
# print(res)
print(chr(res),end="")


ezvm

最后用的时间过长,脑子有点糊掉了,没在规定的时间内做出来,比较可惜。

指令不多

解析一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
'0xb2', '0x0', '0xc4', '0x4', '0xb2', '0x0', '0xc5', '0x6', 
'0xd7',
'0xf4', '0xe2',
'0xd8', '0x3',
'0xc6',

'0xa1',
'0xa2',

'0xb3', '0x0', '0xc4', '0x4', '0xb3', '0x0', '0xc5', '0x6',
'0xd7',
'0xf4', '0xe1',
'0xd8', '0x3',
'0xc6',
'0xa3',
'0x66'

根据功能做详细的解析

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
*v9 = input[nIndex+1]
v25 = input[nIndex+1] << 4 if v11 == 1 else *v9 = v19
v26 = input[nIndex+1] >> 6 if v11 == 1 else *v9 = v19
v24 = xor_v25_v26
v24 = xor_x24_66
v24 += *v9
v18 = dword_41B400[0x3] + v15
v21 = xor_v24_v18
v21 = xor_v21_3

v15 += xor_v16,0x8BE8CF37 0x8BE8CF37 ^ 0xABCDEF12 0x20252025
v14 = v15 >> 7

v20 = input[nIndex] if v11 == 1 else *v20 + v21

v23 = input[nIndex] << 4
v23 = input[nIndex] >> 6
v24 = xor_v25_v26
v24 = xor_x24_66
v22 += v23;
v18 = dword_41B400[0x3] + v15
v21 = xor_v24_v18
v21 = xor_v21_3

v19 = *v9 + v21;

经过简单调试,确定是 Xtea 加密

解密

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

void encipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4])
{
unsigned int i;
uint32_t v0 = v[0], v1 = v[1], sum = 0, delta = 0x20252025;
for (i = 0; i < num_rounds; i++) {
v0 += (((v1 << 4) ^ (v1 >> 6) ^ 66) + v1) ^ (sum + key[sum & 3]) ^ 3;
sum += delta;
v1 += (((v0 << 4) ^ (v0 >> 6) ^ 66) + v0) ^ (sum + key[(sum >> 7) & 3]) ^ 3;
}
v[0] = v0; v[1] = v1;
}

void decipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]) {
unsigned int i;
uint32_t v0 = v[0], v1 = v[1], delta = 0x20252025, sum = delta * num_rounds;
for (i = 0; i < num_rounds; i++) {
v1 -= (((v0 << 4) ^ (v0 >>6) ^ 66) + v0) ^ (sum + key[sum >> 7 & 3]) ^ 3 ;
sum -= delta;
v0 -= (((v1 << 4) ^ (v1 >> 6)^ 66) + v1) ^ (sum + key[sum & 3]) ^ 3 ;
}
v[0] = v0; v[1] = v1;
}


int main()
{


//TestStruct();
unsigned char str[] = { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" };
unsigned char en[] = { 64, 187, 168, 31, 180, 29, 220, 161, 22, 44, 175, 134, 192, 92, 69, 172, 82, 194, 121, 145, 40, 194, 19, 112, 254, 11, 148, 19, 65, 234, 123, 54, 149, 201, 171, 30, 5, 128, 183, 162 };
//sub_402B60(str, 42);

unsigned int v5[22];
unsigned int key[] = { 2,0,2,5 };

v5[0] = 0x1fa8bb40;
v5[1] = 0x34402115;
v5[2] = 0x86af2c16;
v5[3] = 0x547564C9;
v5[4] = 0x9179c252;
v5[5] = 0x2B67FCDE;
v5[6] = 0x13940bfe;
v5[7] = 0x1D47F41A;
v5[8] = 0x1eabc995;
v5[9] = 0x734D7D95;

for (int i = 0; i <= 8; i += 2)
{
decipher(32, (unsigned int*)&v5[i], key);
}
printf("%s", (char*)v5);

return 0;
}

需要注意,对一组加密运算的前4个字节进行了换表运算,需要去反解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21


table = [164, 196, 4, 206, 20, 149, 233, 17, 49, 24, 182, 176, 1, 38, 36, 106, 123, 18, 203, 103, 219, 248, 210, 126, 157, 208, 12, 95, 130, 33, 135, 131, 134, 124, 194, 159, 41, 202, 191, 73, 222, 78, 205, 98, 83, 190, 167, 3, 47, 181, 171, 148, 204, 46, 29, 243, 54, 16, 186, 215, 19, 53, 229, 179, 129, 26, 160, 231, 37, 117, 175, 81, 67, 92, 80, 72, 216, 163, 63, 113, 122, 199, 198, 144, 177, 187, 250, 221, 185, 246, 169, 183, 100, 56, 223, 224, 8, 178, 119, 51, 91, 2, 94, 121, 97, 7, 105, 35, 87, 74, 253, 192, 43, 161, 209, 40, 9, 111, 128, 85, 254, 66, 227, 71, 68, 225, 255, 188, 125, 139, 154, 96, 173, 151, 251, 141, 214, 172, 30, 15, 69, 234, 245, 75, 45, 59, 34, 28, 90, 114, 70, 195, 228, 93, 218, 146, 155, 10, 189, 153, 133, 52, 115, 165, 86, 55, 76, 22, 132, 162, 180, 109, 84, 230, 193, 31, 23, 61, 136, 247, 21, 88, 239, 77, 238, 137, 104, 89, 184, 32, 232, 220, 201, 145, 252, 213, 200, 65, 158, 118, 120, 50, 25, 102, 101, 57, 107, 197, 82, 39, 168, 6, 142, 166, 13, 152, 140, 249, 5, 27, 64, 143, 79, 60, 235, 112, 217, 99, 211, 226, 44, 240, 147, 58, 244, 0, 242, 170, 127, 42, 48, 236, 108, 116, 110, 241, 14, 62, 237, 150, 174, 138, 207, 11, 156, 212]

a_al = bytes.fromhex(
"81 59 84 83 15 21 40 34 d2 53 1f fb c9 64 75 54 c6 fc 42 3b de fc 67 2b 9c b0 5a 67 1a f4 47 1d 72 32 6d 87 95 7d 4d 73")

# a =bytes.fromhex("72 32 6d 87 ")

for j in range(0, len(a_al), 8):
a = a_al[j:j + 4]
bl = []
# print(a)
for i in range(len(a)):
b = table.index(a[i])
bl.append(b)

print(hex(int.from_bytes(bl, byteorder='little')))
# print(bl)

# print(hex(int.from_bytes(a, byteorder='')))

分别替换 0 2 4 6 8 即可 0x1fa8bb40 0x86af2c16 0x9179c252 0x13940bfe 0x1eabc995


2024春秋杯冬季赛-第一天
https://pwner.top/2025/01/17/2024春秋杯-冬季赛/
作者
m1n9yu3
发布于
2025年1月17日
许可协议