2024软件系统安全赛-Reveres-WP

image-20250106111907535

sub_405559就是main函数,其中添加了花指令.

image-20250106112624032

NOP掉即可

image-20250106112740902

两个函数,只是调用方式不同.下个断点跟进查看

image-20250106112909879

输入字符串.

F7跟进

image-20250106113005166

花指令,NOP掉即可

image-20250106113034438

RC4加密初始化,生成密钥流.那么第三个参数就是密钥了.

image-20250106113109370

这里的密钥其实是假的因为动调会改变密钥.

那么不出意外第二个函数就是RC4加密主体了,跟进分析

image-20250106113225113

同样有花指令,NOP掉即可.

image-20250106113254696

RC4加密主体,可以看到最后是多异或了一个0x23.

我们让这个函数执行完毕回到调用的地方.

image-20250106113525108

可以看到当程序执行完r8后,输入字符串就完成了加密保存到了unk_5C6CC0数组下.

image-20250106113610353

关键步骤

这里不再往下跟踪,直接在这个数组上下一个硬件读写断点,查看哪里check了这个数组.

image-20250106113707276

image-20250106113718773

image-20250106113735509

这样下完断点之后,我们直接F4一下,会发现IDA提示

image-20250106113813349

说明00000000005C6CC0处读取或写入了这个数据,我们点击OK跟进去

image-20250106114041377

断在了这里,我们往上翻翻看看这个函数

image-20250106114104895

同样有花指令,NOP掉即可

image-20250106114142345

这里的a2就是在读取加密后的结果,v7就是密文.

RC4解密即可.

真正的RC4 key是

image-20250106114250079

就是没有动态调式下的值,调试下的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
#include<iostream>


void swap(unsigned char* a, unsigned char* b) {
unsigned char temp = *a;
*a = *b;
*b = temp;
}

void rc4_key_setup(unsigned char* key, int key_length, unsigned char S[256]) {
unsigned char T[256];
int i, j;

for (i = 0; i < 256; i++) {
S[i] = i;
T[i] = key[i % key_length];
}

j = 0;
for (i = 0; i < 256; i++) {
j = (j + S[i] + T[i]) % 256;
swap(&S[i], &S[j]);
}
}

void rc4_crypt(unsigned char* input_data, int input_length, unsigned char* output_data, unsigned char S[256]) {
int i, j, k;
i = j = 0;

for (k = 0; k < input_length; k++) {
i = (i + 1) % 256;
j = (j + S[i]) % 256;
swap(&S[i], &S[j]);
int t = (S[i] + S[j]) % 256;
output_data[k] = input_data[k] ^ S[t] ^ 0x23;
}
}

int main()
{
unsigned char key[] = {
0x92, 0x1C, 0x2B, 0x1F, 0xBA, 0xFB, 0xA2, 0xFF, 0x07, 0x69, 0x7D, 0x77, 0x18, 0x8C

};
unsigned char aaaaa[] = {
0x25, 0xCD, 0x54, 0xAF, 0x51, 0x1C, 0x58, 0xD3, 0xA8, 0x4B, 0x4F, 0x56, 0xEC, 0x83, 0x5D, 0xD4,
0xF6, 0x47, 0x4A, 0x6F, 0xE0, 0x73, 0xB0, 0xA5, 0xA8, 0xC3, 0x17, 0x81, 0x5E, 0x2B, 0xF4, 0xF6,
0x71, 0xEA, 0x2F, 0xFF, 0xA8, 0x63, 0x99, 0x57
};

unsigned char output[50]{ 0 };
unsigned char S[256]{ 0 };

rc4_key_setup(key, 14, S);
rc4_crypt(aaaaa, 40, output, S);

for (int i = 0; i < 40; i++) {
printf("%c", output[i]);
}
printf("\n");
}
// dart{y0UD0ntL4cKg0oD3y34T0F1nDTh3B4aUtY}