inctf re 部分wp

比赛时看了4道题,做起了两道,那道vm看太久了,就是爆破脚本有问题。

find_plut0

一道z3约束器求解题,将flag进行两轮计算,但是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
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

from z3 import *

code='inctf{U_Sur3_m4Te?}'

tmp2 = [0] * 19
tmp1 = [0] * 23
len=len(code)
s = Solver()
flag = [BitVec('flag[%d]' % i, 32) for i in range(30)]
tmp1[0] = flag[0] - 50 + flag[1]
tmp1[1] = flag[1] - 100 + flag[2]
tmp1[2] = 4 * flag[2]
tmp1[3] = flag[3] ^ 0x46
tmp1[4] = 36 - (flag[3] - flag[4])
tmp1[6] = flag[6] * flag[5] + 99
tmp1[7] = flag[6] ^ flag[7]
tmp1[8] = (flag[7] + 45) ^ flag[8]
tmp1[9] = (flag[9] & 0x37) - 3
tmp1[11] = flag[11] - 38
tmp1[12] = 4 * ((flag[12] ^ flag[6]) + 4)
tmp1[5] = (flag[21] - flag[4]) ^ 0x30
tmp1[13] = flag[13] - flag[14] - 1
tmp1[10] = flag[17] - flag[16] + 82
tmp1[16] = 6 * (flag[18] ^ flag[19]) + 54
tmp1[17] = flag[21] + 49 + (flag[20] ^ 0x73)
tmp1[14] = flag[22]
tmp1[18] = flag[23] ^ 0x42
tmp1[15] = flag[26] + 5
tmp1[19] = flag[25] - flag[26] / 2 - 55
tmp1[20] = 4 * flag[27] - (flag[28] + 128)
tmp1[21] = flag[29] - 32

tmp2[0] = (tmp1[0] ^ 2) - 31
tmp2[1] = ((tmp1[1] % 2) ^ tmp1[0]) - 29
tmp2[2] = (4 * tmp1[1]) ^ 0x97
tmp2[3] = tmp1[2] ^ 0xA0
tmp2[4] = (tmp1[3] ^ 0x4D) + 7
tmp2[5] = 4 * tmp1[5] - 1
tmp2[3] = tmp1[4] + 116
tmp2[6] = tmp1[6] + 21
tmp2[7] = tmp1[7] - 20
tmp2[8] = tmp1[8] ^ 0x63
tmp2[9] = (tmp1[10] ^ 3) - tmp1[8] + 54
tmp2[10] = tmp1[9] ^ 0x42
tmp2[11] = tmp1[11] + 51
tmp2[11] = tmp1[12] ^ 0xB3
tmp2[12] = (tmp1[13] + 18) ^ 0x1A
tmp2[13] = tmp1[14] - 7
tmp2[14] = tmp1[15] - 37
tmp2[15] = tmp1[17] ^ 0xE5
tmp2[16] = (tmp1[18] & 0x36) + 53
tmp2[14] = tmp1[19] ^ 0x34
tmp2[17] = tmp1[20] ^ 0xFD
tmp2[18] = (tmp1[20] >> tmp1[21]) ^ 0x1C
for i in range(30):
s.add(flag[i]>=0x21)
s.add(flag[i]<=0x7A)
for i in range(len):
s.add(tmp2[i]&0xff==ord(code[i]))

if s.check() == sat:
model = s.model()
str = [chr(model[flag[i]].as_long().real) for i in range(30)]
print("".join(str))
exit()
else:
print("no_sat")
#hTMT0_C0m3@@_m90`z00R_t20ZFbF!

miz

迷宫题,还挺大,25*25,好像还有花,弄得能反编译后去找迷宫,和走迷宫的方式就行了。

迷宫函数,可以用动调来提数据

可以看到是128bit,但是后面一个数就会变成2个64bit,意思就是这个函数中的一个,就是迷宫中的两个。

走迷宫函数

dfs走迷宫

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

//打印迷宫
//#include<stdio.h>
//int main()
//{
// int map[25][25]={1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,1,1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,1,0,1,0,1,1,0,1,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,1,1,0,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,1,0,0,0,1,1,0,1,1,1,1,1,0,1,1,1,0,1,0,1,1,1,0,1,1,1,1,1,0,1,1,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,1,1,1,0,1,0,1,0,1,1,1,1,1,1,1,0,1,1,1,0,1,0,1,1,1,1,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,1,0,1,0,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,0,1,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,1,0,1,0,1,0,1,1,1,0,1,1,1,1,1,0,1,0,1,0,1,0,1,0,1,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,0,0,1,0,0,0,1,0,1,1,0,1,1,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,1,1,1,0,1,1,0,0,0,1,0,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,0,0,1,1,0,1,0,1,0,1,1,1,1,1,1,1,0,1,0,1,1,1,0,1,1,1,0,1,1,0,1,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,1,0,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,0,1,0,1,0,1,0,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,1,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1,0,1,0,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,1,0,1,0,0,0,1,0,1,0,1,1,1,1,0,1,0,1,1,1,0,1,1,1,1,1,0,1,0,1,0,1,0,1,0,1,1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,1,1,1,1,1};
// int i ,j;
// for(i=0; i<25;i++)
// {
// printf("{");
// for(j=0;j<25;j++)
// {
// printf("%-2d,",map[i][j]);
// }
// printf("},\n");
// }
//}


#include<stdio.h>
#include<stdlib.h>


int map[25][25] = {{1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 },
{1 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,1 },
{1 ,0 ,1 ,0 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,0 ,1 ,0 ,1 ,1 ,1 ,0 ,1 ,0 ,1 },
{1 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,1 },
{1 ,0 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,0 ,1 ,0 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,0 ,1 ,1 ,1 ,1 ,1 },
{1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,1 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,1 },
{1 ,0 ,1 ,1 ,1 ,1 ,1 ,0 ,1 ,1 ,1 ,0 ,1 ,0 ,1 ,1 ,1 ,0 ,1 ,1 ,1 ,1 ,1 ,0 ,1 },
{1 ,0 ,0 ,0 ,1 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,1 },
{1 ,1 ,1 ,0 ,1 ,0 ,1 ,0 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,0 ,1 ,1 ,1 ,0 ,1 ,0 ,1 ,1 ,1 },
{1 ,0 ,1 ,0 ,0 ,0 ,1 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,1 },
{1 ,0 ,1 ,0 ,1 ,1 ,1 ,0 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,0 ,1 },
{1 ,0 ,1 ,0 ,1 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,1 },
{1 ,0 ,1 ,0 ,1 ,0 ,1 ,1 ,1 ,0 ,1 ,1 ,1 ,1 ,1 ,0 ,1 ,0 ,1 ,0 ,1 ,0 ,1 ,0 ,1 },
{1 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,1 ,0 ,1 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,1 ,0 ,1 },
{1 ,0 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,0 ,1 ,0 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,0 ,1 },
{1 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,1 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,1 },
{1 ,0 ,1 ,0 ,1 ,0 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,0 ,1 ,0 ,1 ,1 ,1 ,0 ,1 ,1 ,1 ,0 ,1 },
{1 ,0 ,1 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,1 ,0 ,1 ,0 ,1 ,0 ,1 },
{1 ,0 ,1 ,1 ,1 ,1 ,1 ,0 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,0 ,1 ,0 ,1 ,0 ,1 ,0 ,1 },
{1 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,1 ,0 ,1 },
{1 ,0 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,0 ,1 ,0 ,1 ,1 ,1 ,1 ,1 ,0 ,1 ,0 ,1 },
{1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,1 ,0 ,0 ,0 ,1 ,0 ,1 ,0 ,1 },
{1 ,1 ,1 ,0 ,1 ,0 ,1 ,1 ,1 ,0 ,1 ,1 ,1 ,1 ,1 ,0 ,1 ,0 ,1 ,0 ,1 ,0 ,1 ,0 ,1 },
{1 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,1 ,0 ,1 },
{1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,1 ,2 ,1 ,1 ,1 ,1 ,1 ,}};

int mark[25][25] = { 0 };
char way[200];
int index = 0;

void check(int x,int y)
{
if (map[x][y] == 2)
{
printf("way: %s\n", way);
//exit(0);
}
}
void dfs(int x,int y)
{
int xnew=0, ynew=0;
check(x, y);//判断走到终点。
xnew = x - 1;
ynew = y;

if (xnew >= 0 && xnew < 25 && ynew >= 0 && ynew < 25 && map[xnew][ynew] != 1 && mark[xnew][ynew] != 1)//不能越界,不能撞墙,不能走以访问路线。
{
way[index++] = 'j';//保存路线,以便输出路线。
mark[x][y] = 1;//标记以访问路线,避免重复访问。
dfs(xnew, ynew);
mark[x][y] = 0;//如果该路不能到达终点,回溯时要将标记还原。
way[--index] = ' ';//路线走不通,还原。
}

xnew = x;
ynew = y + 1;
if (xnew >= 0 && xnew < 25 && ynew >= 0 && ynew < 25 && map[xnew][ynew] != 1 && mark[xnew][ynew] != 1)
{
way[index++] = 'l';
mark[x][y] = 1;
dfs(xnew, ynew);
mark[x][y] = 0;
way[--index] = ' ';
}

xnew = x + 1;
ynew = y;
if (xnew >= 0 && xnew < 25 && ynew >= 0 && ynew < 25 && map[xnew][ynew] != 1 && mark[xnew][ynew] != 1)
{
way[index++] = 'k';
mark[x][y] = 1;
dfs(xnew, ynew);
mark[x][y] = 0;
way[--index] = ' ';
}

xnew = x;
ynew = y - 1;
if (xnew >= 0 && xnew < 25 && ynew >= 0 && ynew < 25 && map[xnew][ynew] != 1 && mark[xnew][ynew] != 1)
{
way[index++] = 'h';
mark[x][y] = 1;
dfs(xnew, ynew);
mark[x][y] = 0;
way[--index] = ' ';
}


}
int main()
{
int i, j;
for (i = 0; i < 25; i++)
{
for (j = 0; j < 25; j++)
{
printf("%d ", map[i][j]);
}
printf("\n");
}
printf("\n");
dfs(1, 13);
}
//way: llkkhhhhkkkkhhhhjjhhhhhhkkllkkkkkkhhkkllkklljjlllllljjhhjjllllllkklljjllkklljjllkkkkhhhhkkkkllkkkkhhk
//inctf{mizes_are_fun_or_get}

flagchecker

做了很久,就是爆破脚本的问题,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

#include<stdio.h>
//inctf{abcdefghijklmopqrstuvwxyzfsfs}
int opcode[3840]={6,0,11,6,7,4,1,8,0,6,8,11,5,7,4,1,8,1,6,16,11,8,7,4,1,8,2,6,24,11,3,7,4,1,8,3,6,31,11,3,7,4,1,8,4,9,3,140,4,2,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,6,1,11,2,7,4,1,8,0,6,9,11,6,7,4,1,8,1,6,17,11,1,7,4,1,8,2,6,25,11,0,7,4,1,8,3,9,3,225,4,2,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,6,2,11,0,7,4,1,8,0,6,10,11,4,7,4,1,8,1,6,18,11,5,7,4,1,8,2,6,26,11,2,7,4,1,8,3,6,32,11,3,7,4,1,8,4,9,3,299,4,2,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,6,3,11,8,7,4,1,8,0,6,11,11,5,7,4,1,8,1,6,19,11,3,7,4,1,8,2,6,27,11,7,7,4,1,8,3,9,3,359,4,2,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,6,4,11,3,7,4,1,8,0,6,12,11,8,7,4,1,8,1,6,20,11,3,7,4,1,8,2,6,28,11,8,7,4,1,8,3,6,33,11,3,7,4,1,8,4,9,3,689,4,2,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,6,5,11,6,7,4,1,8,0,6,13,11,5,7,4,1,8,1,6,21,11,5,7,4,1,8,2,6,29,11,6,7,4,1,8,3,9,3,400,4,2,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,6,6,11,1,7,4,1,8,0,6,14,11,0,7,4,1,8,1,6,22,11,4,7,4,1,8,2,6,30,11,2,7,4,1,8,3,6,34,11,5,7,4,1,8,4,9,3,500,4,2,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,6,7,11,5,7,4,1,8,0,6,15,11,3,7,4,1,8,1,6,23,11,1,7,4,1,8,2,6,35,11,8,7,4,1,8,3,9,3,491,4,2,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,5,10,3,129,4,12,5,12,5,12,5,12,5,12,5,12,5,12,5,12,5,12,};
char talble[350]="ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff30030587801234562301034123801234412115345567801232762751324567803356468145234567423634656801234567801234567801234567801234567801234567801234567801234567801234567801234567801234567801234567801248577878274567801215767600234567086284567Good Job!";
int main()
{
int i,k;
int v7=0;
char a[5]="";
for ( i = 0; i <= 3829; i += v7 )
{
switch ( opcode[i] )
{
case 1:
printf("mov eax table[ebx]\n");
v7 = 1;
break;
case 2:
puts("Checking flag...\n");
v7 = 1;
break;
case 3:
printf("mov ebx %d\n",opcode[i + 1]) ;
v7 = 2;
break;
case 4:
printf("mov ebx hex(ebx)\n");
v7 = 1;
break;
case 5:
printf("add ebx 1 k=%d\n",k);
k++;
v7 = 1;
break;
case 6:
printf("mov eax flag[%d]\n",opcode[i + 1]) ;
v7 = 2;
break;
case 7:
printf("mov ebx eax\n");
v7 = 1;
break;
case 8:
printf("new[%d]=eax\n",opcode[i + 1]);
v7 = 2;
break;
case 9:
printf("func(new[] to array[])\n");
k=0;
v7 = 1;
break;
case 10:
printf("cmp talbe[ebx] array[k++]\n");
v7 = 1;
break;
case 11:
printf("check eax mod 9 == %d\n",opcode[i + 1]);
v7 = 2;
break;
case 12:
printf("good\n");
v7 = 1;
break;
default:
continue;
}
}

}

得到如下

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

mov eax flag[0]
check eax mod 9 == 6//有这个约束条件就可以得到准确的flag。
mov ebx eax
mov ebx hex(ebx)//这个hex的意思是将flag[0]转为int,然后在前面直接加上0x,比如说flag[0]=105,就会变成0x105
mov eax table[ebx]
new[0]=eax//将table[ebx]的值给一个数组,这个数组会作为下面func()函数的参数,然后函数是switch case和很多包含fork()函数的函数,根据new[]的不同,就会产生不同的长字符串。
mov eax flag[8]
check eax mod 9 == 5
mov ebx eax
mov ebx hex(ebx)
mov eax table[ebx]
new[1]=eax
mov eax flag[16]
check eax mod 9 == 8
mov ebx eax
mov ebx hex(ebx)
mov eax table[ebx]
new[2]=eax
mov eax flag[24]
check eax mod 9 == 3
mov ebx eax
mov ebx hex(ebx)
mov eax table[ebx]
new[3]=eax
mov eax flag[31]
check eax mod 9 == 3
mov ebx eax
mov ebx hex(ebx)
mov eax table[ebx]
new[4]=eax
func(new[] to array[])
mov ebx 140
mov ebx hex(ebx)
Checking flag...//然后比较

cmp talbe[ebx] array[k++]
add ebx 1 k=0
cmp talbe[ebx] array[k++]
add ebx 1 k=1
cmp talbe[ebx] array[k++]
add ebx 1 k=2
cmp talbe[ebx] array[k++]
add ebx 1 k=3
cmp talbe[ebx] array[k++]
add ebx 1 k=4
cmp talbe[ebx] array[k++]
add ebx 1 k=5
cmp talbe[ebx] array[k++]
add ebx 1 k=6
cmp talbe[ebx] array[k++]
···
···

上面的只是一轮,共8轮,每次回用到4~5个flag字符。每轮大概思路就是几个flag字符生成一个new数组,然后new数组通过一个函数生成一个比较长的字符串,然后和程序给定的值进行比较。

接下来来看func()函数,也就是sub_117B()

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

char *__fastcall sub_117B(const char *new_1)
{
char src; // [rsp+17h] [rbp-39h] BYREF
int i; // [rsp+18h] [rbp-38h]
__pid_t v4; // [rsp+1Ch] [rbp-34h]
FILE *stream; // [rsp+20h] [rbp-30h]
char *v6; // [rsp+28h] [rbp-28h]
char *dest; // [rsp+30h] [rbp-20h]
unsigned __int64 v8; // [rsp+38h] [rbp-18h]

v8 = __readfsqword(0x28u);
v6 = (char *)malloc(0x1F4uLL);
dest = (char *)malloc(0x1F4uLL);
v4 = getpid(); // 得到父进程的pid
for ( i = 0; i < strlen(new_1); ++i )
{
switch ( new_1[i] ) // 下面的函数,里面就是fork()函数,和给malloc申请的v6赋值,对于fork()这个函数,其会返回2次,然后根据不同的判断条件,又会产生多种可能,就是存在超多个进程,所以就算是一个字符,也会变成字符串,这也是为什么程序中字符串那么长的原因
{
case '0':
sub_CCE(v6);
break;
case '1':
sub_D33(v6);
break;
case '2':
sub_DB3(v6);
break;
case '3':
sub_E33(v6);
break;
case '4':
sub_EF4(v6);
break;
case '5':
sub_F59(v6);
break;
case '6':
sub_101C(v6);
break;
case '7':
sub_10C6(v6);
break;
case '8':
sub_1129(v6);
break;
default:
continue;
}
}
stream = fopen("check", "at"); // 打开或创建check文件,用来保存v6
if ( !stream )
stream = fopen("check", "wt");
if ( !stream )
{
printf("Can not open check file for writing.");
exit(0);
}
fputs(v6, stream); // 将v6写入check文件
fclose(stream);
if ( v4 != getpid() ) // 确定返回了父进程
exit(0);
sleep(1u);
stream = fopen("check", "r"); // 以读的方式来打开check函数
if ( !stream )
puts("Cannot open check file for reading");
for ( src = fgetc(stream); src != -1; src = fgetc(stream) )// 读入dest
strncat(dest, &src, 1uLL);
if ( remove("check") ) // 删除check文件
puts("\nUnable to delete the file");
return dest; // 返回dest
}

到这里,我就想能不能直接通过fork()函数产生的字符串直接得到new[],但是最多就减少一些爆破的字符,而且出题人在社区里面发了一段话

For flagchecker, it becomes way easier if you get the parent process from each cmp string. Parent process's output for each set of 4/5 char will always be at the end(thanks to multiple wait checks in the functions). If you can figure out the parent, you can   actually figure out the path it takes checking which all numbers that are being appended into the check file from the parent. That narrows it down a lot. And then it's just trying out the different path that parent might takes out of those.

对于flagchecker,如果您从每个cmp字符串中获取父进程,它将变得更加容易。父进程对每组4/5字符的输出将始终位于末尾(由于函数中有多个等待检查)。如果您可以找出父项,那么实际上可以找出检查从父项追加到检查文件中的所有数字所采用的路径。这就缩小了范围。然后,它只是尝试不同的路径,家长可能会采取这些。

确实也只能减少爆破范围,于是做题时我就仿照程序写了个脚本,并且可以根据inctf{}格式来减少爆破范围。

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

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include <sys/types.h>
#include <wait.h>
#include"defs.h"


char str[133]="3433423443344234633462346334623133123143314231633162316331622432422443244224632";

int sub_CCE(const char *a1)
{
char *v1; // rax

if ( fork() || !fork() )
{
LODWORD(v1) = wait(0LL);
}
else
{
wait(0LL);
v1 = (char *)&a1[strlen(a1)];
*(_WORD *)v1 = 53;
}

}

char * sub_D33(const char *a1)
{
char *result; // rax

if ( fork() )
{
wait(0LL);
result = (char *)&a1[strlen(a1)];
*(_WORD *)result = 49;
}
else
{
result = (char *)&a1[strlen(a1)];
*(_WORD *)result = 52;
}
}

char * sub_DB3(const char *a1)
{
char *result; // rax

if ( fork() )
{
wait(0LL);
result = (char *)&a1[strlen(a1)];
*(_WORD *)result = 50;
}
else
{
result = (char *)&a1[strlen(a1)];
*(_WORD *)result = 51;
}

}

int sub_E33(const char *a1)
{
char *v1; // rax

LODWORD(v1) = fork();
if ( (_DWORD*)v1 )
{
wait(0LL);
LODWORD(v1) = fork();
if ( (_DWORD*)v1 )
{
wait(0LL);
if ( fork() )
{
wait(0LL);
LODWORD(v1) = fork();
if ( (_DWORD*)v1 )
{
wait(0LL);
v1 = (char *)&a1[strlen(a1)];
*(_WORD *)v1 = 53;
}
}
else
{
v1 = (char *)&a1[strlen(a1)];
*(_WORD *)v1 = 51;
}
}
}

}

int sub_EF4(const char *a1)
{
char *v1; // rax

LODWORD(v1) = fork();
if ( (_DWORD*)v1 )
{
wait(0LL);
if ( fork() )
{
LODWORD(v1) = wait(0LL);
}
else
{
v1 = (char *)&a1[strlen(a1)];
*(_WORD *)v1 = 52;
}
}

}

char * sub_F59(const char *a1)
{
char *result; // rax

if ( fork() )
{
wait(0LL);
if ( fork() )
{
wait(0LL);
result = (char *)&a1[strlen(a1)];
*(_WORD *)result = 53;
}
else
{
result = (char *)&a1[strlen(a1)];
*(_WORD *)result = 51;
}
}
else
{
result = (char *)&a1[strlen(a1)];
*(_WORD *)result = 52;
}

}

int sub_101C(const char *a1)
{
char *v1; // rax

LODWORD(v1) = fork();
if ( (_DWORD*)v1 )
{
wait(0LL);
if ( fork() || fork() )
{
wait(0LL);
wait(0LL);
v1 = (char *)&a1[strlen(a1)];
*(_WORD *)v1 = 54;
}
else
{
v1 = (char *)&a1[strlen(a1)];
*(_WORD *)v1 = 52;
}
}

}

int sub_10C6(const char *a1)
{
char *v1; // rax

LODWORD(v1) = fork();
if ( (_DWORD*)v1 )
{
wait(0LL);
LODWORD(v1) = fork();
if ( (_DWORD*)v1 )
{
wait(0LL);
v1 = (char *)&a1[strlen(a1)];
*(_WORD *)v1 = 51;
}
}

}

int sub_1129(const char *a1)
{
char *v1; // rax

if ( fork() )
{
LODWORD(v1) = wait(0LL);
}
else
{
v1 = (char *)&a1[strlen(a1)];
*(_WORD *)v1 = 50;
}

}

char* func(const char *a1)
{
char *v6;
char *dest;
char src;
__pid_t v4;
FILE *stream;
v6 = (char *)malloc(0x2e4uLL);
dest = (char *)malloc(0x2e4uLL);
int i;
v4= getpid();
for ( i = 0; i < strlen(a1); ++i )
{
switch ( a1[i] )
{
case '0':
sub_CCE(v6);
break;
case '1':
sub_D33(v6);
break;
case '2':
sub_DB3(v6);
break;
case '3':
sub_E33(v6);
break;
case '4':
sub_EF4(v6);
break;
case '5':
sub_F59(v6);
break;
case '6':
sub_101C(v6);
break;
case '7':
sub_10C6(v6);
break;
case '8':
sub_1129(v6);
break;
default:
continue;
}
}
stream = fopen("check", "at");
if ( !stream )
stream = fopen("check", "wt");
if ( !stream )
{
printf("Can not open check file for writing.");
exit(0);
}
fputs(v6, stream);
fclose(stream);
if ( v4 != getpid() )
{
exit(0);
}
stream = fopen("check", "r");
if ( !stream )
{
puts("Cannot open check file for reading");
}

for ( src = fgetc(stream); src != -1; src = fgetc(stream) )
{
strncat(dest, &src, 1uLL);
}
remove("check") ;
return dest;
}
int main()
{
char a,b,c,d,e;
char tmp[6];
char *code=malloc(0x2e4uLL);

for(a='0';a<='8';a++)
{
for(b='0';b<='8';b++)
{
for(c='0';c<='8';c++)
{
for(d='0';d<='8';d++)
{
for(e='0';e<='8';e++)
{
tmp[0]=a;
tmp[1]=b;
tmp[2]=c;
tmp[3]=d;
tmp[4]=e;
tmp[5]='\0';
printf("%s\n",tmp);
code=func(tmp);
printf("%s\n",code);
if(!memcmp(code, str,11))
{
//printf("%s\n",tmp);
//printf("%s\n",code);
}
free(code);
}

}
}
}
}
}

脚本确实有用,但是比较字符串基本没用,因为产生的字符串只能满足大部分相同,并且在看wp时用正确的new数组去生成字符串,也只能满足大部分相同,可能某个地方出了点问题,但用这种方式也确实得到了一些正确字符。

inctf{ MhW1 Y_ 0tv) x) RocA 5E 990 }

然后就看wp了,看了无名侠师傅的wp,发现其方法是直接patch程序,让输入直接变为4~5个字符然后去调用哪个函数,然后用pwntools交互,打印出所有可能,然后比较。

最后就直接贴一个官方wp吧

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

weird_arr = open("flagchecker","rb").read()[0x2020:0x2848]

pos_vals = [
[[0 , 6], [8 , 5], [16 , 8], [24 , 3], [31 , 3],],
[[1 , 2], [9 , 6], [17 , 1], [25 , 0],],
[[2 , 0], [10 , 4], [18 , 5], [26 , 2], [32 , 3],],
[[3 , 8], [11 , 5], [19 , 3], [27 , 7],],
[[4 , 3], [12 , 8], [20 , 3], [28 , 8], [33 , 3],],
[[5 , 6], [13 , 5], [21 , 5], [29 , 6],],
[[6 , 1], [14 , 0], [22 , 4], [30 , 2], [34 , 5],],
[[7 , 5], [15 , 3], [23 , 1], [35 , 8],],
]

checks = [
'84721',
'1138',
'80481',
'7786',
'57518',
'2445',
'02162',
'1854',
]

flag = [0] * 36

for i in range(len(checks)):
chk = checks[i]
psv = pos_vals[i]

print(psv)

for x in range(len(chk)):
for ch in range(30,127):
if chr(weird_arr[int(str(ch),16)]) == chk[x]:
if (ch % 9) == psv[x][1]:
# print(chr(ch))
flag[psv[x][0]] = chr(ch)
break

# print(flag)
print("".join(flag))
#inctf{vM_W1ht_l0t7_0f_pRoces5ES9902}

REplica

rust,之前见过一次,确实难看,根据题目来看,应该是换位。

然后ida看了看,能确定字符长度是25,但当时就是不知道怎么输入,后来看wp才知道是命令行输入,对于命令行输入如何调试还没想好,应该是是main函数传入的参数,但是暂时没去实践。

Adventures of Lonely Knight

nes,全新的知识点,参考无名侠wphttps://panda0s.top/2021/08/16/InCTF2021/,去下载模拟器调了调。虽然没完全搞懂,但是也比较好玩。

用模拟器打开文件,用手柄的start开始游戏,键盘居然还晓不得哪个是开始,游戏过程大概就是打怪,吃心心,捡钥匙进入下一关,但是玩了一会你就会发现,结果都是you died,也比较奇怪这道题也没说过关条件,不像mrctf的游戏,给了过关条件。

然后去找一些地址代表的意思,如下,调很多次就能发现主要代码就在0xA200的后面。

重点来说一下0x5C的几个值的意思吧,因为0x68的key分析不来,不知道为什么非0就可以得到flag。如果要分析死亡条件,由于调试时人不能动,但是游戏中的怪会随着调试自动移动,我就想下几个断点,看看判断条件是什么,结果也没看到什么cmp。

当0x5C的值为1,就是正常的游戏过程。

当0x5C的值为3,结束屏幕会闪。

当0x5C的值为4,会冒出一个通关的界面。

当0x5C的值为5,弹出you died界面,我也是通过每次死亡后发现这个地址的值都会变为5,从而特地分析的什么改变了0x5C地址的值。

最后就贴一个直接改key的成功得到flag界面吧,还会变色,估计和0x5C=3有关。

INCTF{LONELY_BOY_1E23}