看雪CTF2021

看雪CTF2021

第二题 南冥神功

简单迷宫题

map1 = [0x0, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00]

1
2
3
4
5
6
7
8
for y in range(9):
line = ''
for x in range(10):
if theMap[y * 10 + x] == 0:
line = line + "."
else:
line = line + "#"
print(line)
1
2
3
4
5
6
7
8
9
..#..#..##
##..#..#..
..#.#####.
.##.#..#..
..#..#..##
##.###.#.#
..####.#.#
.##..#.#.#
...#..##..

.data:004B7040 a0123456789abcd db ‘0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ’,0
loc_4B3DC5: ; what is ecx
mov eax, ecx
‘0’ => 0
‘1’ => 1
‘2’ => 2
‘9’ => 9
‘A’ => 0xA
‘F’ => 0xF

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
alpha = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
i_1 => alpha.index(flag[flagPos])
v8 = i_1 + flagPos;
v10 = 5 - v8 % 6;
switch ( v10 )

case 1
x = x + 1
case 4
x = x - 1

case 2:
y 为偶数, x = x + 1
y = y + 1

default
如果 y 为偶数, x = x + 1
y = y - 1

case 3:
如果 y 为奇数, x = x - 1
y = y + 1

case 5
如果 y 为奇数, x = x - 1
y = y - 1

一位flag字符决定两个方向指令
v2 = (flagPos + flagIdx / 6) % 6;
v1 = cur = 5 - (flagPos + flagIdx ) % 6;
爆破 flagIdx 即可

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
map1 = [0x1, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00]


def checkValid(theMap, x, y):
if x < 0 or y < 0:
return False
if x > 9 or y > 8:
return False
return theMap[y * 10 + x] == 0


def isAllClear(theMap):
return sum(theMap) == 90


def genNextValid(theMap, x, y):
insList = []
# case1
if checkValid(theMap, x + 1, y):
insList.append((1, x + 1, y))

# case4
if checkValid(theMap, x - 1, y):
insList.append((4, x - 1, y))

if y % 2 == 0:
# case2
if checkValid(theMap, x + 1, y + 1):
insList.append((2, x + 1, y + 1))
# default
if checkValid(theMap, x + 1, y - 1):
insList.append((-1, x + 1, y - 1))
# case3
if checkValid(theMap, x, y + 1):
insList.append((3, x, y + 1))
# case5
if checkValid(theMap, x, y - 1):
insList.append((5, x, y - 1))
else:
# case2
if checkValid(theMap, x, y + 1):
insList.append((2, x, y + 1))
# default
if checkValid(theMap, x, y - 1):
insList.append((-1, x, y - 1))
# case3
if checkValid(theMap, x - 1, y + 1):
insList.append((3, x - 1, y + 1))
# case5
if checkValid(theMap, x - 1, y - 1):
insList.append((5, x - 1, y - 1))
return insList


def dfs(CurMap, curX, curY, InsList):
CurMap = CurMap.copy()
CurMap[curY * 10 + curX] = 1

if isAllClear(CurMap):
print("Find Solve.")
print(InsList)
for y in range(9):
line = ''
for x in range(10):
if CurMap[y * 10 + x] == 0:
line = line + "."
else:
line = line + "#"
print(line)
return InsList


curInsList = genNextValid(CurMap, curX, curY)
if len(curInsList) == 0:
return None

result = None
for i in curInsList:
InsList.append(i)
dfs(CurMap, i[1], i[2], InsList)
InsList.pop()
return result


dfs(map1, 0, 0, [])

# alpha = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
# i_1 => alpha.index(flag[flagPos])
# v8 = i_1 + flagPos;
# v10 = 5 - v8 % 6;
alpha = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
target = [(1, 1, 0), (2, 2, 1), (3, 1, 2), (4, 0, 2), (3, 0, 3), (2, 0, 4), (1, 1, 4), (2, 2, 5), (3, 1, 6), (4, 0, 6), (3, 0, 7), (2, 0, 8), (1, 1, 8), (1, 2, 8), (-1, 3, 7), (1, 4, 7), (2, 4, 8), (1, 5, 8), (-1, 6, 7), (-1, 6, 6), (5, 6, 5), (-1, 6, 4), (5, 6, 3), (4, 5, 3), (3, 4, 4), (4, 3, 4), (5, 3, 3), (-1, 3, 2), (5, 3, 1), (-1, 3, 0), (1, 4, 0), (2, 5, 1), (1, 6, 1), (-1, 6, 0), (1, 7, 0), (2, 8, 1), (1, 9, 1), (2, 9, 2), (3, 9, 3), (4, 8, 3), (3, 7, 4), (2, 8, 5), (2, 8, 6), (3, 8, 7), (2, 8, 8), (1, 9, 8)]
flagPos = 0
realPos = 0
v7 = 0
flag = ''
for i in range(0, len(target), 2):
step1 = target[i][0]
step2 = target[i + 1][0]
flagPos = i // 2

if step1 == -1:
step1 = 0

if step2 == -1:
step2 = 0

FindAns = None
for idx in range(len(alpha)):
v7 = (flagPos + idx // 6) % 6
v6 = 5 - (idx + flagPos) % 6
if v6 == step1 and v7 == step2:
FindAns = idx

flag += alpha[FindAns]
print(flag)

第四题 英雄救美

sub_391240 对输入数据进行转换
这个函数有点小坑…..

1
table1 = [0x24, 0x42, 0x50, 0x56, 0x3A, 0x75, 0x62, 0x66, 0x59, 0x70, 0x7D, 0x5D, 0x44, 0x74, 0x4E, 0x3E, 0x61, 0x54, 0x5E, 0x4D, 0x47, 0x6D, 0x4A, 0x51, 0x23, 0x2A, 0x48, 0x72, 0x60, 0x4F, 0x27, 0x77, 0x6A, 0x69, 0x63, 0x30, 0x21, 0x68, 0x64, 0x79, 0x7B, 0x6F, 0x5A, 0x7A, 0x2D, 0x40, 0x6E, 0x2B, 0x3F, 0x26, 0x25, 0x73, 0x5F, 0x2F, 0x67, 0x3C, 0x65, 0x5B, 0x57, 0x29, 0x58, 0x55, 0x78, 0x52, 0x46, 0x53, 0x4C, 0x52, 0x41, 0x3B, 0x2E, 0x6C, 0x3D, 0x43, 0x45, 0x6B, 0x76, 0x4B, 0x2D, 0x28, 0x71]

$B$BP => 12123

sub_391000 9x9 数独 check

1
2
3
4
5
6
7
8
map1 = [0x00000000, 0x00000004, 0x00000000, 0x00000007, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009, 0x00000002, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000006, 0x00000000, 0x00000007, 0x00000008, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000005, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000002, 0x00000000, 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000005, 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000004, 0x00000009, 0x00000000, 0x00000000, 0x00000000, 0x00000007, 0x00000001, 0x00000003, 0x00000000, 0x00000005, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000009, 0x00000004, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008, 0x00000000, 0x00000006, 0x00000000]

mat = []
for y in range(9):
line = list()
for x in range(9):
line.append(map1[y * 9 + x])
mat.append(line)

数独输出如下

1
2
3
4
5
6
7
8
9
0 4 0 7 0 0 0 0 0
9 2 0 0 0 0 6 0 7
8 3 0 0 0 5 4 0 0
0 1 0 0 0 3 0 0 0
0 0 0 2 0 1 0 0 0
0 0 0 5 0 0 0 4 0
0 0 4 9 0 0 0 7 1
3 0 5 0 0 0 0 9 4
0 0 0 0 0 8 0 6 0

用 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
X = [ [ Int("x_%s_%s" % (i+1, j+1)) for j in range(9) ] 
for i in range(9) ]

cells_c = [ And(1 <= X[i][j], X[i][j] <= 9)
for i in range(9) for j in range(9) ]

rows_c = [ Distinct(X[i]) for i in range(9) ]

cols_c = [ Distinct([ X[i][j] for i in range(9) ])
for j in range(9) ]

sq_c = [ Distinct([ X[3*i0 + i][3*j0 + j]
for i in range(3) for j in range(3) ])
for i0 in range(3) for j0 in range(3) ]

sudoku_c = cells_c + rows_c + cols_c + sq_c

instance = [[0, 4, 0, 7, 0, 0, 0, 0, 0],
[9, 2, 0, 0, 0, 0, 6, 0, 7],
[8, 3, 0, 0, 0, 5, 4, 0, 0],
[0, 1, 0, 0, 0, 3, 0, 0, 0],
[0, 0, 0, 2, 0, 1, 0, 0, 0],
[0, 0, 0, 5, 0, 0, 0, 4, 0],
[0, 0, 4, 9, 0, 0, 0, 7, 1],
[3, 0, 5, 0, 0, 0, 0, 9, 4],
[0, 0, 0, 0, 0, 8, 0, 6, 0]]

instance_c = [ If(instance[i][j] == 0,
True,
X[i][j] == instance[i][j])
for i in range(9) for j in range(9) ]

s = Solver()
s.add(sudoku_c + instance_c)
if s.check() == sat:
m = s.model()
r = [ [ m.evaluate(X[i][j]) for j in range(9) ]
for i in range(9) ]
print_matrix(r)
else:
print ("failed to solve")

得到结果

1
2
3
4
5
6
7
8
9
result = [[5, 4, 6, 7, 1, 9, 2, 3, 8],
[9, 2, 1, 8, 3, 4, 6, 5, 7],
[8, 3, 7, 6, 2, 5, 4, 1, 9],
[7, 1, 8, 4, 6, 3, 9, 2, 5],
[4, 5, 3, 2, 9, 1, 7, 8, 6],
[6, 9, 2, 5, 8, 7, 1, 4, 3],
[2, 8, 4, 9, 5, 6, 3, 7, 1],
[3, 6, 5, 1, 7, 2, 8, 9, 4],
[1, 7, 9, 3, 4, 8, 5, 6, 2]]

反推输入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
dict_map = {}
for k in range(len(table1)):
kk = k % 9 + 1
if kk not in dict_map:
dict_map[kk] = []
dict_map[kk].append(table1[k])

for kk in dict_map:
print(kk, dict_map[kk])

flag = ''
for y in range(9):
cnt = 0
for x in range(9):
if instance[y][x] == 0:
flag = flag + chr(dict_map[result[y][x]][y])
cnt = cnt + 1
flag = flag + chr(ord('9') - cnt)
print(flag)

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!