vnctf2023 Rewp

VNCTF2023 rewp

PZGalaxy

打开发现是个网站,f12查看源码

image-20230713025229628

image-20230710013800090

rc4加密,密钥的长度为8位且前四位已给出

爆破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
def rc4_encrypt(m, key):
s = []
t = []
out = [] # putput
for i in range(256):
s.append(i)
t.append(ord(key[i % len(key)]))

j = 0
for i in range(256):
j = (j + s[i] + t[i]) % 256
s[i], s[j] = s[j], s[i]

i, j = 0, 0
for p in range(len(m)):
i = (i + 1) % 256
j = (j + s[i]) % 256

s[i], s[j] = s[j], s[i]

index = (s[i] + s[j]) % 256
out.append(s[index] ^ m[p])
return out


def dfs(key):
if len(key) > 8:
return
x = '0123456789'
if len(key) == 8:
print(key)
out = rc4_encrypt(c, key)
if out[0] == ord('f') and out[1] == ord('l') and out[2] == ord('a') and out[3] == ord('g'):
for t in out:
print(chr(t), end="")
exit(0)
return
for i in range(10):
tmp = key + x[i]
dfs(tmp)
return


c = [166, 112, 58, 220, 146, 195, 151, 243, 26, 223, 8, 214, 65, 160, 53, 144, 123, 6, 212, 247, 115, 95, 29, 58, 73,
76, 67, 88, 209, 185, 79, 153, 133, 51, 224, 105, 124]

if __name__ == '__main__':
dfs('2023')

flag{HitYourSoulAndSeeYouInTheGalaxy}

confuse_re

image-20230710010110112

很明显框中的部分是多余的

花指令,用idapython去除,不过这个脚本功能不算特别完善有些地方得手动在ida里面调整

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
from ida_bytes import *
from ida_funcs import *


def check(addr):
# push rbp call $+5
x = [0x55, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x5d]
buf = get_bytes(addr, 7)
for i in range(7):
if buf[i] != x[i]:
return False
return True


if __name__ == '__main__':
start_addr = 0x004011b0
end_addr = 0x004b4560

for i in range(start_addr, end_addr, 1):
if check(i):
st = i
end = st + 7
while get_byte(end) != 0x5d:
end += 1
end += 1
for j in range(st, end):
patch_byte(j, 0x90)
while get_byte(end) != 0xc3:
end += 1
end += 1
set_func_end(st, end)
print(hex(end))
i = end

然后是aes,类似CBC的模式,但是魔改了,加了个异或0x23

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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
#include<iostream>
#include<string.h>
#define uint8 unsigned char
#define uint32 unsigned int
uint8_t sbox[256] =
{
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16
};

uint8_t inv_s[256] = {
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
};
uint8_t rcon[11] = { 0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1B, 0x36 };
uint8_t GFMul(uint8_t a, uint8_t b) {

uint8_t sig = 0, ans = 0;
while (a)
{
if (a & 1) ans ^= b;
a >>= 1;
if (a) {
sig = (b >> 7) & 1;
b <<= 1;
if (sig) b ^= 0x1B;
}
}
return ans;
}
void get_rk(uint8* k, uint8* w) {
uint8 tmp[4];
memcpy(w, k, 16);
for (int i = 4; i < 44; i++) {
tmp[0] = w[4 * (i - 1)];
tmp[1] = w[4 * (i - 1) + 1];
tmp[2] = w[4 * (i - 1) + 2];
tmp[3] = w[4 * (i - 1) + 3];
if (i % 4 == 0) {

tmp[0] = sbox[w[4 * (i - 1) + 1]];
tmp[1] = sbox[w[4 * (i - 1) + 2]];
tmp[2] = sbox[w[4 * (i - 1) + 3]];
tmp[3] = sbox[w[4 * (i - 1)]];

*(uint8*)tmp ^= rcon[i / 4];

}
w[4 * i] = w[4 * (i - 4)] ^ tmp[0];
w[4 * i + 1] = w[4 * (i - 4) + 1] ^ tmp[1];
w[4 * i + 2] = w[4 * (i - 4) + 2] ^ tmp[2];
w[4 * i + 3] = w[4 * (i - 4) + 3] ^ tmp[3];
}
}

void add_key(uint8* m, uint8* k, int len) {
for (int i = 0; i < len; i++)
m[i] ^= k[i]^0x23;
}

void sub_byte(uint8* m, int len) {
for (int i = 0; i < len; i++)
m[i] = sbox[m[i]];
}

void shift_row(uint8* m) {
uint8 sig, tmp, i, j;
for (i = 1; i < 4; i++) {
sig = 0;
while (sig < i)
{
tmp = m[i];
for (j = 0; j < 3; j++)
m[i + 4 * j] = m[i + 4 * (j + 1)];
m[i + 4 * j] = tmp;
sig += 1;
}
}
}
void mix_col(uint8* m) {
uint8 tmp[16];
memcpy(tmp, m, 16);
for (int i = 0; i < 16; i += 4) {
m[i] = GFMul(2, tmp[i]) ^ GFMul(3, tmp[i + 1]) ^ tmp[i + 2] ^ tmp[i + 3];
m[i + 1] = tmp[i] ^ GFMul(2, tmp[i + 1]) ^ GFMul(3, tmp[i + 2]) ^ tmp[i + 3];
m[i + 2] = tmp[i] ^ tmp[i + 1] ^ GFMul(2, tmp[i + 2]) ^ GFMul(3, tmp[i + 3]);
m[i + 3] = GFMul(3, tmp[i]) ^ tmp[i + 1] ^ tmp[i + 2] ^ GFMul(2, tmp[i + 3]);
}
}
void inv_sub_byte(uint8* m, int len) {
for (int i = 0; i < len; i++)
m[i] = inv_s[m[i]];
}
void inv_mix_col(uint8* m) {
uint8 tmp[16];
memcpy(tmp, m, 16);
for (int i = 0; i < 16; i += 4) {
m[i] = GFMul(0xe, tmp[i]) ^ GFMul(0xb, tmp[i + 1]) ^ GFMul(0xd, tmp[i + 2]) ^ GFMul(0x9, tmp[i + 3]);
m[i + 1] = GFMul(0x9, tmp[i]) ^ GFMul(0xe, tmp[i + 1]) ^ GFMul(0xb, tmp[i + 2]) ^ GFMul(0xd, tmp[i + 3]);
m[i + 2] = GFMul(0xd, tmp[i]) ^ GFMul(0x9, tmp[i + 1]) ^ GFMul(0xe, tmp[i + 2]) ^ GFMul(0xb, tmp[i + 3]);
m[i + 3] = GFMul(0xb, tmp[i]) ^ GFMul(0xd, tmp[i + 1]) ^ GFMul(0x9, tmp[i + 2]) ^ GFMul(0xe, tmp[i + 3]);
}
}
void inv_shift_row(uint8* m) {
uint8 sig, tmp, i, j;
for (i = 1; i < 4; i++) {
sig = 0;
while (sig < i)
{
tmp = m[i + 12];
for (j = 3; j > 0; j--)
m[i + 4 * j] = m[i + 4 * (j - 1)];
m[i] = tmp;
sig += 1;
}
}
}
void aes_encry(uint8* m, uint8* rk) {
int i;
add_key(m, rk, 16);
for (i = 1; i < 10; i++) {
sub_byte(m, 16);
shift_row(m);
mix_col(m);
add_key(m, rk + 16 * i, 16);
}
sub_byte(m, 16);
shift_row(m);
add_key(m, rk + 16 * i, 16);
}

void aes_decry(uint8* m, uint8* rk) {
int i;
add_key(m, rk + 160, 16);
for (i = 9; i > 0; i--) {
inv_sub_byte(m, 16);
inv_shift_row(m);
add_key(m, rk + 16 * i, 16);
inv_mix_col(m);
}
inv_sub_byte(m, 16);
inv_shift_row(m);
add_key(m, rk + 16 * i, 16);
}
void hexdump(uint8* m, int len) {
for (int i = 0; i < len; i++)
printf("%02x", m[i]);
printf("\n");
}
int main() {
char k[17] = { 0xCA, 0x9D, 0x7F, 0xF8, 0xA4, 0x09, 0x90, 0x04, 0xFA, 0xD4, 0x06, 0x61, 0xE9, 0x3B, 0x77, 0x5A };
char m[33] = { 0xDC, 0xDC, 0xCC, 0x66, 0x8D, 0xF3, 0x3C, 0x15, 0x50, 0x5E, 0xEF, 0x16, 0x46, 0xD9, 0xD7, 0xDF, 0x50, 0x27, 0x44, 0x77, 0x65, 0xDC, 0xA7, 0x39, 0x68, 0xCB, 0x7F, 0x7B, 0x88, 0xDD, 0x64, 0x0F };
unsigned int w[44];
get_rk((uint8*)k, (uint8*)w);

aes_decry((uint8*)m+16, (uint8*)w);
for (int i = 0; i < 16; i++) {
m[16 + i] = (m[16 + i] - 1) ^ m[i];
}
aes_decry((uint8*)m, (uint8*)w);
printf("VNCTF{%s}", m);
return 0;
}

VNCTF{fa9ad36bd2de1586d944cf7b2935dd91}

BabyAnti

安卓题,这里使用反作弊。

So层

检测系统为测试版还是正式发布版

在常用目录下检测su指令

image-20230710220518228

在进程表中搜索是否有frida及其相关进程

image-20230710220727174

smali检测

image-20230710224844120

将HP和分数保存并异或防止被直接搜索到,然后再将当前值和被保存的值进行比较,如果不一样则说明被修改了

选择将函数b返回值改为true

image-20230710224752047

重打包后成功修改分数

img

flag{D1n0_Run_0ut_0f_The_F0rest_F1nally^_^}

dll_puzzle

这道题主打一个塞爆,几乎常见的反调试都塞进去了

首先这是一个dll文件,使用regsvr32或rundll32直接运行,或者写一个程序去加载dll然后再利用ida进行调试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <Windows.h>
#include <stdio.h>

int main() {
LoadLibraryA("advapi32.dll");
LoadLibraryA("user32.dll");
HINSTANCE hDllInst = LoadLibraryA("RegisterServer.dll");
if (hDllInst != NULL) {
printf("load success!\n");
return 0;
}
while (1)
{
printf("123456");
}
return 0;
}

ida64打开,除了dllmain之外还有一个tls函数,这些都是需要重点关注的函数

image-20230712214631002

分析TLS函数

首先是这个函数

image-20230712214735864
函数利用Win32API的hashcode在对应dll中加载Win32API

image-20230712214935598

去除花指令后,首先获取kernel32的地址,目的是获取GetProcAddress()的地址

kernel32.dll里有一个GetProcAddress函数,可以找到模块中的函数地址

这里利用PEB进行跳转,eax = 0x30

image-20230712215215285

1
2
3
4
5
6
7
8
9
10
GetKernel32Base proc
assume fs:nothing ;开始使用fs寄存器
mov eax, dword ptr fs : [30h] ;指向PEB结构
mov eax, dword ptr[eax + 0Ch] ;指向LDR Ptr32 _PEB_LDR_DATA
mov eax, dword ptr[eax + 0Ch] ;指向InLoadOrderModuleList _LIST_ENTRY
mov eax, dword ptr[eax] ;移动_LIST_ENTRY
mov eax, dword ptr[eax] ;指向Kernel32
mov eax, dword ptr[eax + 18h] ;指向DllBase基址
ret
GetKernelBase endp

附上两篇看雪的博客

详解七句汇编获取Kernel32模块地址

https://bbs.kanxue.com/thread-270431.htm

完美实现GetProcAddress

https://bbs.kanxue.com/thread-121226.htm

进入下面的sm3函数

首先是获取以输入的dll_addr为基址的导出表详情

image-20230712220622852

对应的结构体为

1
2
3
4
5
6
7
8
9
10
11
12
13
typedef struct _IMAGE_EXPORT_DIRECTORY {
DWORD Characteristics;
DWORD TimeDateStamp;
WORD MajorVersion;
WORD MinorVersion;
DWORD Name;
DWORD Base;
DWORD NumberOfFunctions;
DWORD NumberOfNames;
DWORD AddressOfFunctions; // RVA from base of image
DWORD AddressOfNames; // RVA from base of image
DWORD AddressOfNameOrdinals; // RVA from base of image
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;

Base 函数以序号导出的时候的序号基数,从这个数开始递增
NumberOfFunctions 本dll一共有多少个导出函数,不管是以序号还是以函数名导出
NumberOfFunctions 本dll中以能够以函数名称导出的函数个数(注意,说一下,其实函数里的每一个函数都能通过序号导出,但是为了兼容性等等,也给一些函数提供用函数名称来导出)
AddressOfFunctions 指向一个DWORD数组首地址,共有NumberOfFunctions 个元素,每一个元素都是一个函数地址
AddressOfNames 指向一个DWORD数组首地址,共有NumberOfNames个元素,每一个元素都是一个字符串(函数名字符串)首地址
AddressOfNameOrdinals指向一个WORD数组首地址,共有NumberOfNames个元素,每一个元素都是一个函数序号
我们说的最后俩数组,其实是一种一一对应的关系,假如分别叫 dwNames[] 和 dwNamesOrdinals[],
假如dwNames[5]的值(这个指是一个地址,前面都说了)指向的字符串等于“GetValue”,那么dwNamesOrdinals[5]的值(这个指是一个序号,前面都说了),就是GetValue导出函数的序号啦,那么怎样找到地址呢?
这时候就需要用到第一个数组了,假如名字叫dwFuncAddress[], GetValue的导出地址就是
dwFuncAddress[dwNamesOrdinals[5]] + 模块基址

最后,利用sm3运算再与0x9e3779b进行异或并比较从而确定函数、返回函数调用地址。

image-20230712221007391

可以通过动调来确定具体调用了哪个API

image-20230712223551127

继续往下分析,发现有大量CreateMuteA的函数,可以通过动调获取其值

image-20230712223910190

image-20230712223841398

再往下分析,就开始反调试了

首先是根据进程名字进行反调试

image-20230712224220790

image-20230712224306287

覆盖面相当的广,不过只是单纯的判断,patch就行了

再之后是三连反调试

image-20230712225205890

甚至还写了真假两个sm4

image-20230712225322980

分析dllmain函数

首先通过动调恢复符号

image-20230713002834011

这里动态计算了一个crc32的值,主要目的是防止下断,但似乎没什么意义,纯摆设

剩下就没什么反调试了,唯一的坑就是这里的atoi函数其实自己写的,用于初始化sm4的密钥

image-20230713003845982

image-20230713004025718

接下来,动态得出v73的值为42

image-20230713003951598

动态atoi函数得到key

1
20 62 32 33 2e 74 76 2f 79 46 52 43 37 68 59 00

image-20230713004310667

对应的视频就是【【官方 MV】Never Gonna Give You Up - Rick Astley】 https://www.bilibili.com/video/BV1GJ411x7h7/?share_source=copy_web&vd_source=94f4709cb1337b391b88cdb3116e04b8

下面是对输入的校验

image-20230713004743179

之后就是sm4的加密了

image-20230713004920372

加密后是crc校验和方程组

image-20230713004951946

z3

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
from z3 import *

sm4k = [0x0A, 0x48, 0x18, 0x19, 0x04, 0x5E, 0x5C, 0x05, 0x53, 0x6C, 0x78, 0x69, 0x1D, 0x42, 0x73, 0x2A]
sm4k = [i ^ 42 for i in sm4k]
buf = [Int("m%d" % i) for i in range(80)]
s = Solver()
s.add(5 * buf[1] + 8 * buf[0] == 2669)
s.add(6 * buf[1] + 4 * buf[2] == 1402)
s.add(3 * buf[3] + 6 * buf[2] == 873)
s.add(7 * buf[4] + 6 * buf[3] == 2627)
s.add(8 * buf[5] + 4 * buf[4] == 2516)
s.add(9 * buf[6] + 5 * buf[5] == 2781)
s.add(3 * buf[6] + 4 * buf[7] == 1228)
s.add(5 * buf[8] + 9 * buf[7] == 1821)
s.add(7 * buf[9] + 5 * buf[8] == 554)
s.add(6 * buf[10] + 9 * buf[9] == 825)
s.add(5 * buf[11] + 6 * buf[10] == 1857)
s.add(3 * buf[11] + 4 * buf[12] == 1627)
s.add(7 * buf[13] + 5 * buf[12] == 2279)
s.add(3 * buf[14] + 9 * buf[13] == 1974)
s.add(6 * buf[15] + 6 * buf[14] == 2382)
s.add(7 * buf[15] + 8 * buf[16] == 1903)
s.add(8 * buf[17] + 8 * buf[16] == 1336)
s.add(3 * buf[18] + 6 * buf[17] == 822)
s.add(5 * buf[19] + 8 * buf[18] == 381)
s.add(3 * buf[20] + 5 * buf[19] == 823)
s.add(5 * buf[21] + 5 * buf[20] == 1680)
s.add(6 * buf[21] + 8 * buf[22] == 2116)
s.add(9 * buf[23] + 3 * buf[22] == 1059)
s.add(3 * buf[23] + 8 * buf[24] == 1314)
s.add(3 * buf[25] + 9 * buf[24] == 1641)
s.add(5 * buf[25] + 8 * buf[26] == 2148)
s.add(3 * buf[27] + 3 * buf[26] == 669)
s.add(5 * buf[28] + 9 * buf[27] == 953)
s.add(5 * buf[29] + 7 * buf[28] == 1896)
s.add(3 * buf[30] + 3 * buf[29] == 1275)
s.add(5 * buf[31] + 7 * buf[30] == 2874)
s.add(9 * buf[32] + 6 * buf[31] == 1518)
s.add(7 * buf[33] + 5 * buf[32] == 1312)
s.add(6 * buf[34] + 5 * buf[33] == 2148)
s.add(9 * buf[34] + 8 * buf[35] == 2979)
s.add(3 * buf[35] + 4 * buf[36] == 476)
s.add(6 * buf[37] + 3 * buf[36] == 1047)
s.add(7 * buf[38] + 4 * buf[37] == 1488)
s.add(6 * buf[39] + 6 * buf[38] == 1320)
s.add(5 * buf[40] + 6 * buf[39] == 1784)
s.add(3 * buf[41] + 8 * buf[40] == 1994)
s.add(7 * buf[42] + 3 * buf[41] == 712)
s.add(3 * buf[43] + 3 * buf[42] == 1002)
s.add(5 * buf[44] + 7 * buf[43] == 2094)
s.add(3 * buf[45] + 3 * buf[44] == 465)
s.add(5 * buf[46] + 6 * buf[45] == 1479)
s.add(3 * buf[47] + 6 * buf[46] == 1281)
s.add(7 * buf[48] + 4 * buf[47] == 1064)
s.add(3 * buf[49] + 4 * buf[48] == 985)
s.add(3 * buf[50] + 4 * buf[49] == 922)
s.add(7 * buf[51] + 8 * buf[50] == 1672)
s.add(9 * buf[51] + 4 * buf[52] == 1740)
s.add(6 * buf[53] + 7 * buf[52] == 1185)
s.add(6 * buf[54] + 9 * buf[53] == 711)
s.add(4 * buf[55] + 4 * buf[54] == 256)
s.add(7 * buf[56] + 8 * buf[55] == 744)
s.add(5 * buf[57] + 8 * buf[56] == 1674)
s.add(6 * buf[58] + 3 * buf[57] == 834)
s.add(3 * buf[59] + 4 * buf[58] == 348)
s.add(9 * buf[59] + 4 * buf[60] == 952)
s.add(3 * buf[60] + 4 * buf[61] == 1117)
s.add(7 * buf[62] + 9 * buf[61] == 1853)
s.add(6 * buf[63] + 9 * buf[62] == 399)
s.add(3 * buf[64] + 6 * buf[63] == 1011)
s.add(6 * buf[65] + 9 * buf[64] == 3171)
s.add(8 * buf[66] + 8 * buf[65] == 1760)
s.add(7 * buf[67] + 7 * buf[66] == 861)
s.add(6 * buf[68] + 6 * buf[67] == 1710)
s.add(7 * buf[68] + 8 * buf[69] == 1578)
s.add(7 * buf[70] + 9 * buf[69] == 1280)
s.add(3 * buf[71] + 6 * buf[70] == 1134)
s.add(3 * buf[72] + 8 * buf[71] == 1003)
s.add(9 * buf[72] + 8 * buf[73] == 1345)
s.add(5 * buf[74] + 4 * buf[73] == 928)
s.add(3 * buf[74] + 4 * buf[75] == 824)
s.add(6 * buf[76] + 8 * buf[75] == 1840)
s.add(9 * buf[77] + 7 * buf[76] == 1200)
s.add(3 * buf[77] + 8 * buf[78] == 2032)
s.add(5 * buf[79] + 5 * buf[78] == 1795)
s.add(7 * buf[79] + 8 * buf[0] == 2584)
if s.check() == sat:
result = s.model()
for each in buf:
print(hex(result[each].as_long()), end="")
else:
print("no")

最后丢进CyberChef

image-20230713005407608

flag{3f27d7470d8967fd344ec7f1261e64b3}

将flag的16进制输入license.ini,运行得

image-20230713005751196

jijiji

发现程序创建了一个子进程,ida attach,甚至连参数都能看到

image-20230713023658172

过反调试后就是一个魔改过的tea

image-20230713024815152

脚本

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
#include <cstdio>
#include <cstring>
#include <iostream>


using namespace std;

void decrypt(unsigned long* EntryData, unsigned long* key)
{
unsigned long Mup = EntryData[0];
unsigned long Mdown = EntryData[1];
unsigned long delta = 0x88408067;
unsigned long sum = delta * 33;
int n = 33;

for(int i=0;i<n;i++){
sum -= delta;
Mdown -= (key[(sum >> 11) & 3] + sum) ^ (Mup + ((Mup >> 5) ^ (16 * Mup)));
Mup -= sum ^ (key[sum & 3] + sum) ^ (Mdown + ((Mdown >> 5) ^ (16 * Mdown)));
}

EntryData[0] = Mup;
EntryData[1] = Mdown;
}

int main()
{
unsigned int flag[8] = {
0xADD4F778, 0xA6D7F132, 0x61813290, 0x2D4A40A6, 0x00B05F11, 0xB6D59424, 0x231BBFC6, 0xCD405B31
};
unsigned long key[] = {'b', 'o', 'm', 'b'};
unsigned long k[] = {0x1234567, 0x89ABCDEF};
for(int i = 0; i < 4; i++) {
unsigned long tmp[2];
tmp[0] = flag[2*i];
tmp[1] = flag[2*i + 1];
decrypt(tmp, key);
for (int j = 0; j < 2; j++) {
for (int k = 0; k < 4; k++) {
printf("%c", tmp[j] & 0xff);
tmp[j] >>= 8;
}
}
}
return 0;
}

vnctf{2d326e43eb8fea8837737fc0f50f83f2}