avatar

GKCTF (week 6)

之前奶奶生病,大概照顾了一周,来到青岛这边后,开始更新一下博客,周末有时间就没赶上GKCTF,凌晨正好有时间,都做一下,争取都ak一下!😘

Check_1n

打开后

image-20200526022217284

发现是一个字符搞的一个计算机,直接ida看一下

image-20200526022334570

看到了关键的地方,拿去base64一下:

image-20200526023200161

发现这个flag并不是正确的,在看了看,发现了关键的地方

image-20200526023236391

image-20200526023426729

这里直接base58

image-20200526023312990

BabyDriver

拿到后,看到是一个.sys的文件,一个驱动文件,想了一下好像还要双机调试,直接学驱动的时候 用windbg,于是乎我先放进ida看看

image-20200526023909366

看到这里,猜测百分之99,都是个迷宫题

image-20200526023932114

果断,整理一下

1
2
3
4
5
6
7
8
9
10
11
12
13
o.*..*......*..*
*.**...**.*.*.**
*.****.**.*.*.**
*...**....*.*.**
***..***.**.*..*
*.**.***.**.**.*
*.**.******.**.*
*.**....***.**.*
*.*****.***....*
*...***.********
**..***......#**
**.*************
****************

image-20200526025231590

23 37 36 38 对应了 :I K J L 那么上下左右大概知道了 上 I 左 J 右 L 下 K

flag{LKKKLLKLKKKLLLKKKLLLLLL} 去md5一下

image-20200526025539568

flag{403950a6f64f7fc4b655dea696997851}

Chelly’s identity

emmm,题目说你有听说过chelly吗?我去百度了一下chelly

image-20200526030119579

好的 不知道是啥东西!还是ida吧

image-20200526030238818

c++写的继续分析了

image-20200526030640423

长度16

image-20200526030823868

这里应该是加密函数

image-20200526143010519

进去看了一下这里应该是一个判断质数的东西,从2 - 128 进行删选

image-20200526144809336

上面的一系列算法满足的是斐波那契数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//前两个数为1,1。先定义前两个变量a,b。第三个数为前两两个数之和,定义第三个变量c,c=a+b;现在有三个数,为了避免冗余,把第二个数的值赋给a,第三个数的值赋给b,c=a+b得到第四个数,以此类推…
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n = 0;
int a = 1;
int b = 1;
int c = 0;
int i = 0;
scanf("%d", &n);
printf("%5d %5d ", a, b);
for (i = 0; i < n - 2;i++)
{
c = a + b;
a = b;
b = c;
printf("%5d ", c);
}
printf("\n");
system("pause");
return 0;
}

看了一下,差不多,是一样的,那么思路就是,我们输入了16个数后,经过斐波那契数的原则假设得到x,我们输入的数是y,进行一个 y^x 与我们之后的check进行比较,大概就是这样,比较的数据就是

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
v6 = 438;
v7 = 1176;
v8 = 1089;
v9 = 377;
v10 = 377;
v11 = 1600;
v12 = 924;
v13 = 377;
v14 = 1610;
v15 = 924;
v16 = 637;
v17 = 639;
v18 = 376;
v19 = 566;
v20 = 836;
v21 = 830;

可以进行一个爆破

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
x = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127 ]
y = [438,1176,1089,377,377,1600,924,377,1610,924,637,639,376,566,836,830 ]
flag = ''
for i in y:
for j in range(128):
z = 0
k = 0
while x[k] < j:
z = x[k] + z
k = k + 1
a = j ^ z
if a == i:
flag += chr(j)
print(flag)
//Che11y_1s_EG0IST

EzMachine

看一下源码吧VM的题

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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
// flag: GWHT{Y0u_hav3_r3v3rs3_1t!}
char *vm_stack;
int len = 0;
char enc[] = {0x69, 0x45, 0x2a, 0x37, 0x9, 0x17, 0x6dc5, 0x5b0b, 0x705c, 0x72, 0x33, 0x76, 0x33, 0x21, 0x74, 0x31, 0x5f, 0x33, 0x73, 0x72};
char enc_flag[] = {0x46, 0x7a, 0x7b, 0x61, 0x4d, 0x7b, 0x61, 0x4d, 0x7c, 0x7d, 0x66, 0x4d, 0x74, 0x7e, 0x73, 0x75, 0x4d, 0x20, 0x21, 0x21};
enum opcodes
{
MOV = 0xf1,
XOR = 0xf2,
RET = 0xf4,
READ = 0xf5,
ADD = 0xf6,
MUL = 0xf7,
EXCH = 0xf8,
};
unsigned char vm_code[] = {
0xf5,
0xf1,0xe1,0x0,0x00,0x00,0x00,0xf2,0xf1,0xe4,0x20,0x00,0x00,0x00,
0xf1,0xe1,0x1,0x00,0x00,0x00,0xf2,0xf1,0xe4,0x21,0x00,0x00,0x00,
0xf1,0xe1,0x2,0x00,0x00,0x00,0xf2,0xf1,0xe4,0x22,0x00,0x00,0x00,
0xf1,0xe1,0x3,0x00,0x00,0x00,0xf2,0xf1,0xe4,0x23,0x00,0x00,0x00,
0xf1,0xe1,0x4,0x00,0x00,0x00,0xf2,0xf1,0xe4,0x24,0x00,0x00,0x00,
0xf1,0xe1,0x5,0x00,0x00,0x00,0xf2,0xf1,0xe4,0x25,0x00,0x00,0x00,
0xf1,0xe1,0x6,0x00,0x00,0x00,0xf2,0xf1,0xe4,0x26,0x00,0x00,0x00,
0xf1,0xe1,0x7,0x00,0x00,0x00,0xf2,0xf1,0xe4,0x27,0x00,0x00,0x00,
0xf1,0xe1,0x8,0x00,0x00,0x00,0xf2,0xf1,0xe4,0x28,0x00,0x00,0x00,
0xf1,0xe1,0x9,0x00,0x00,0x00,0xf2,0xf1,0xe4,0x29,0x00,0x00,0x00,
0xf1,0xe1,0xa,0x00,0x00,0x00,0xf2,0xf1,0xe4,0x2a,0x00,0x00,0x00,
0xf1,0xe1,0xb,0x00,0x00,0x00,0xf2,0xf1,0xe4,0x2b,0x00,0x00,0x00,
0xf1,0xe1,0xc,0x00,0x00,0x00,0xf2,0xf1,0xe4,0x2c,0x00,0x00,0x00,
0xf1,0xe1,0xd,0x00,0x00,0x00,0xf2,0xf1,0xe4,0x2d,0x00,0x00,0x00,
0xf1,0xe1,0xe,0x00,0x00,0x00,0xf2,0xf1,0xe4,0x2e,0x00,0x00,0x00,
0xf1,0xe1,0xf,0x00,0x00,0x00,0xf2,0xf1,0xe4,0x2f,0x00,0x00,0x00,
0xf1,0xe1,0x10,0x00,0x00,0x00,0xf2,0xf1,0xe4,0x30,0x00,0x00,0x00,
0xf1,0xe1,0x11,0x00,0x00,0x00,0xf2,0xf1,0xe4,0x31,0x00,0x00,0x00,
0xf1,0xe1,0x12,0x00,0x00,0x00,0xf2,0xf1,0xe4,0x32,0x00,0x00,0x00,
0xf1,0xe1,0x13,0x00,0x00,0x00,0xf2,0xf1,0xe4,0x33,0x00,0x00,0x00,
0xf4
};
enum regist
{
R1 = 0xe1,
R2 = 0xe2,
R3 = 0xe3,
R4 = 0xe5,
};

typedef struct
{
unsigned char opcode;
void (*handle)(void *);
}vm_opcode;

typedef struct
{
int r1;
int r2;
int r3;
int r4;
unsigned char *eip;
vm_opcode op_list[7];
}vm_cpu;


unsigned char true_vm_code[] = {
0xf5,//read(0,buf,0x20)
0xf1,0xe1,0x0,0x0,0x0,0x0,//r1 = flag[0]
0xf1,0xe2,0x1,0x0,0x0,0x0,//r2 = flag[1]
0xf2,//r1 = 0x12^r1^r2
0xf1,0xe4,0x0,0x0,0x0,0x0,//stack[0] = r1

0xf1,0xe1,0x1,0x0,0x0,0x0,//r1 = flag[1]
0xf1,0xe2,0x2,0x0,0x0,0x0,//r2 = flag[2]
0xf2,//r1 = 0x12^r1^r2
0xf1,0xe4,0x1,0x0,0x0,0x0,//stack[1] = r1

0xf1,0xe1,0x2,0x0,0x0,0x0,//r1 = flag[2]
0xf1,0xe2,0x3,0x0,0x0,0x0,//r2 = flag[3]
0xf2,//r1 = 0x12^r1^r2
0xf1,0xe4,0x2,0x0,0x0,0x0,//stack[2] = r1

0xf1,0xe1,0x3,0x0,0x0,0x0,//r1 = flag[3]
0xf1,0xe2,0x4,0x0,0x0,0x0,//r2 = flag[4]
0xf2,//r1 = 0x12^r1^r2
0xf1,0xe4,0x3,0x0,0x0,0x0,//stack[3] = r1

0xf1,0xe1,0x4,0x0,0x0,0x0,//r1 = flag[4]
0xf1,0xe2,0x5,0x0,0x0,0x0,//r2 = flag[5]
0xf2,//r1 = 0x12^r1^r2
0xf1,0xe4,0x4,0x0,0x0,0x0,//stack[4] = r1

0xf1,0xe1,0x5,0x0,0x0,0x0,//r1 = flag[5]
0xf1,0xe2,0x6,0x0,0x0,0x0,//r2 = flag[6]
0xf2,//r1 = 0x12^r1^r2
0xf1,0xe4,0x5,0x0,0x0,0x0,//stack[5] = r1

0xf1,0xe1,0x6,0x0,0x0,0x0,//r1 = flag[6]
0xf1,0xe2,0x7,0x0,0x0,0x0,//r2 = flag[7]
0xf1,0xe3,0x8,0x0,0x0,0x0,//r3 = flag[8]
0xf1,0xe5,0xC,0x0,0x0,0x0,//r4 = flag[12]
0xf6, //r1 = (3*r1+2*r2+r3)
0xf7, //r1 = r1*r4
0xf1,0xe4,0x6,0x0,0x0,0x0,//stack[6] = r1

0xf1,0xe1,0x7,0x0,0x0,0x0,//r1 = flag[7]
0xf1,0xe2,0x8,0x0,0x0,0x0,//r2 = flag[8]
0xf1,0xe3,0x9,0x0,0x0,0x0,//r3 = flag[9]
0xf1,0xe5,0xC,0x0,0x0,0x0,//r4 = flag[12]
0xf6, //r1 = (3*r1+2*r2+r3)
0xf7, //r1 = r1*r4
0xf1,0xe4,0x7,0x0,0x0,0x0,//stack[7] = r1

0xf1,0xe1,0x8,0x0,0x0,0x0,//r1 = flag[8]
0xf1,0xe2,0x9,0x0,0x0,0x0,//r2 = flag[9]
0xf1,0xe3,0xA,0x0,0x0,0x0,//r3 = flag[10]
0xf1,0xe5,0xC,0x0,0x0,0x0,//r4 = flag[12]
0xf6, //r1 = (3*r1+2*r2+r3)
0xf7, //r1 = r1*r4
0xf1,0xe4,0x8,0x0,0x0,0x0,//stack[8] = r1

0xf1,0xe1,0xD,0x0,0x0,0x0,//r1 = flag[13]
0xf1,0xe2,0x13,0x0,0x0,0x0,//r2 = flag[19]
0xf8,//r1 = r2,r2 = r1
0xf1,0xe4,0xD,0x0,0x0,0x0,//stack[13] = r1
0xf1,0xe7,0x13,0x0,0x0,0x0,//stack[19] = r2

0xf1,0xe1,0xE,0x0,0x0,0x0,//r1 = flag[14]
0xf1,0xe2,0x12,0x0,0x0,0x0,//r2 = flag[18]
0xf8,//r1 = r2,r2 = r1
0xf1,0xe4,0xE,0x0,0x0,0x0,//stack[14] = r1
0xf1,0xe7,0x12,0x0,0x0,0x0,//stack[18] = r2

0xf1,0xe1,0xF,0x0,0x0,0x0,//r1 = flag[15]
0xf1,0xe2,0x11,0x0,0x0,0x0,//r2 = flag[17]
0xf8,//r1 = r2,r2 = r1
0xf1,0xe4,0xF,0x0,0x0,0x0,//stack[15] = r1
0xf1,0xe7,0x11,0x0,0x0,0x0,//stack[17] = r2
0xf4//ret
};

void mov(vm_cpu *cpu);
void add(vm_cpu *cpu);
void xor(vm_cpu *cpu);
void read_(vm_cpu *cpu);
void ret(vm_cpu *cpu);
void mul(vm_cpu *cpu);
void exch(vm_cpu *cpu);

void exch(vm_cpu *cpu)
{
int temp1;
temp1 = cpu->r1;
cpu->r1 = cpu->r2;
cpu->r2 = temp1;
cpu->eip += 1;
}

void ret(vm_cpu *cpu)
{
cpu->eip += 1;
return 0;
}
void add(vm_cpu *cpu)
{
cpu->r1 = 3*(cpu->r1) + 2*(cpu->r2) + cpu->r3;
cpu->eip += 1;
}
void mul(vm_cpu *cpu)
{
cpu->r1 = cpu->r1*cpu->r4;
cpu->eip += 1;
}

void xor(vm_cpu *cpu)
{
int temp;
temp = cpu->r1^cpu->r2;
cpu->r1 = temp;
cpu->eip += 1;
}

void read_(vm_cpu *cpu)
{
char *dest = vm_stack;
read(0,dest,0x20);
len = strlen(dest);
if(len!=21)
{
puts("WRONG!");
exit(0);
}
cpu->eip += 1;
}

void mov(vm_cpu *cpu)
{
//mov指令的参数都隐藏在字节码中,指令表示后的一个字节是寄存器标识,第二到第五是要mov的数据在vm_stack上的偏移
unsigned char *res = cpu->eip + 1;
int *offset = (int *)(cpu->eip + 2);
char *dest = 0;
dest = vm_stack;
switch(*res){

case 0xe1:
cpu->r1 = *(dest + *offset);
break;
case 0xe2:
cpu->r2 = *(dest + *offset);
break;
case 0xe3:
cpu->r3 = *(dest + *offset);
break;
case 0xe5:
cpu->r4 = *(dest + *offset);
break;
case 0xe4:
{
int x;
x = cpu->r1;
*(dest + *offset) = x;
break;
}
case 0xe7:
{
int y;
y = cpu->r2;
*(dest + *offset) = y;
break;
}

}
cpu->eip += 6;//control by ourselves
}

void vm_init(vm_cpu *cpu)
{
cpu->r1 = 0;
cpu->r2 = 0x12;
cpu->r3 = 0;
cpu->r4 = 0;
cpu->eip = (unsigned char *)vm_code;
cpu->op_list[0].opcode = 0xf1;
cpu->op_list[0].handle = (void (*)(void *))mov;

cpu->op_list[1].opcode = 0xf2;
cpu->op_list[1].handle = (void (*)(void *))xor;

cpu->op_list[2].opcode = 0xf5;
cpu->op_list[2].handle = (void (*)(void *))read_;

cpu->op_list[3].opcode = 0xf4;
cpu->op_list[3].handle = (void (*)(void *))ret;

cpu->op_list[4].opcode = 0xf7;
cpu->op_list[4].handle = (void (*)(void *))mul;

cpu->op_list[5].opcode = 0xf8;
cpu->op_list[5].handle = (void (*)(void *))exch;

cpu->op_list[6].opcode = 0xf6;
cpu->op_list[6].handle = (void (*)(void *))add;

vm_stack = malloc(0x512);
memset(vm_stack,0,0x512);
}

void vm_start(vm_cpu *cpu)
{
cpu->eip = (unsigned char*)vm_code;
while (*cpu->eip!=RET)
{
vm_dispatcher(cpu);
}
}

void vm_dispatcher(vm_cpu *cpu)
{
int i = 0;
while (1)
{
if(*cpu->eip == cpu->op_list[i].opcode)
{
cpu->op_list[i].handle(cpu);
break;
}
else
{
i += 1;
}
}
}
void check2()
{
int i;
char *target = vm_stack;
for(i = 0; i < len - 1; i++)
{
if((char)target[i] != enc[i])
{
exit(0);
}
}
}

void check()
{
int i;
char *target = vm_stack;
for(i = 0; i < len - 1; i++)
{
if((char)target[i+0x20] != enc_flag[i])
{
puts("WRONG!");
exit(0);
}
}
puts("Congratulation?");
puts("tips: input is the start");
}

int main(int argc, char const *argv[])
{
vm_cpu *cpu = {0};
puts("Please input something:");
vm_init(&cpu);
vm_start(&cpu);
check();
puts("And the flag is GWHT{true flag}");
exit(0);
}
Author: L0x1c
Link: https://l0x1c.github.io/2020/05/26/2020-5-26/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Donate
  • 微信
    微信
  • 支付寶
    支付寶