难得做出有点技术含量的杂项题:

解压给出两个图片,一个压缩包

flag.rar里面有个flag.php,有加密:

看下两个图片,占用空间比较大,肯定藏了东西:

此图片的alt属性为空;文件名为image-1.png

先看了下属性,没东西,binwalk走一下有两个rar压缩包

解压,一个hint一个excel

password.xls里发现256*256的 大小写字母、数字,并且在右上角有一个规则范围全是等于号,很容易联想到base64,于是我们仔细查看hint.txt里的内容:

此图片的alt属性为空;文件名为image-4-1024x268.png

可以看到是一段hex文本,上面提示password是base64编码,下面是一段字母数字,可以联想到是编码的文字的开头,结合excel里左上角位置的初始字符,我们可以联想到excel里的内容是将编码后的字符通过一定规则排列了,我们就按照hint里的文本,将excel里的字符画出排列的路径,可以看到是这样:

这路径,熟不熟悉?这就是大名鼎鼎的希尔伯特曲线。

wiki百科

找了一个python脚本,看看各阶希尔伯特曲线的样子:

1阶

2阶

4阶

而8阶希尔伯特曲线就是这道题的256*256范围的了:

8阶

我们从左上角开始,按照这个曲线的顺序,就能将256*256的所有字符遍历并转化成一维的字符串了

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
# encoding=utf-8

import numpy as np
import copy
import xlrd

def conv2_1D(n):
"""
功能:将二维坐标映射到一维
输入:生成阶数(2^n*2^n)
输出:一维数组
"""
temp00 = [[0, 2**n-2], [0, 2**n-1], [1, 2**n-1], [1, 2**n-2]]
for i in range(1,n):
temp0 = np.array(temp00)
temp1 = temp0 - [0, 2**i]
for item in temp1:
item[0], item[1] = item[1]-2**n+2**(i+1), item[0]+2**n-2**(i+1)
temp10 = np.vstack((temp1, temp0))
temp20 = copy.deepcopy(temp10)
for item in temp20:
v = 2**i-0.5
item[0] = 2*v-item[0]
temp30 = temp20[::-1]
temp00 = np.vstack((temp10, temp30)).tolist()

return temp00
# 可以自行尝试用递归实现



excel = xlrd.open_workbook(r'E:\Desktop\21长城杯\misc\你这flag保熟吗\你这flag保熟吗\password.xls')
print('此文件含有的工作表:', excel.sheet_names())
table = excel.sheets()[0]
print('表行数:', table.nrows)
print('表列数:', table.ncols, end='\n\n\n==============================================\n')

excelData = []
for i in range(table.nrows):
excelData.append(table.row_values(i))
# print(excelData)

# for i in excelData:
# for n in i:
# print(n, end='; ')
# print('\n=============================================================')
# print(excelData[0])

data = conv2_1D(8)
print(data[65535])

xyfile = open(r'E:\Desktop\21长城杯\misc\你这flag保熟吗\你这flag保熟吗\xy.txt', 'w')
outfile = open(r'E:\Desktop\21长城杯\misc\你这flag保熟吗\你这flag保熟吗\out.txt', 'w')

for item in data:
outfile.write(excelData[item[1]][item[0]])
xyfile.write(str(item[0]) + ' ' + str(item[1]) + '\n')

得到按顺序遍历的坐标和还原了顺序的编码:

而excel里的那一大块范围等于号,还原后就是还原了顺序的编码的最后一部分:

可想而知是套了不知道多少层的base64,在很多层的解码后还原了字符串:

用这串密码解压flag.rar,得到flag.php:

很明显是一段brainfuck代码,但是你怎么运行都只显示error,于是学了下brainfuck:

程序的最后一段有五个输出,这五个输出就是输出error这个字符串,估计是用来迷惑解题人以为出错了,搞了我好久!

点字符表示输出当前指针内容

所以我们要输出前面没有输出的字符,我将前面的每个循环结尾都加了<.>>来输出没有输出的字符,结果也确实能输出结果,但是总是少几个字符。最后用脚本跑出来了:

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
def interp(code):
data = [0 for i in range(1000)]
pc = 0
ptr = 0
skip_loop = False
bracket_count = 0
stack = []
while pc < len(code):
c = code[pc]
if skip_loop :
if c =='[':
bracket_count+=1
elif c==']':
bracket_count -=1
if bracket_count==0:
skip_loop =False
pc+=1
continue
if c == '>':
ptr +=1
pc +=1
elif c == '<':
ptr -=1
pc +=1
elif c == '+':
data[ptr] +=1
pc +=1
elif c == '-':
data[ptr] -=1
pc +=1
elif c == '.':
for a in range(41):
print(chr(data[a]),end="")
exit()
pc +=1
elif c == ',':
pc +=1
elif c == '[':
if data[ptr] == 0:
#nonlocal bracket_count,skip_loop
bracket_count = 1
skip_loop = True
pc+=1
else:
pc+=1
stack.append(pc)
elif c == ']':
if data[ptr] == 0:
pc+=1
stack.pop()
else:
pc = stack[len(stack)-1]

#interp('++++.>>++.')
#interp('+++++.>++.[-<+>]<.')
interp('>+++++++++[<+++++++++++++>-]>+++[<+++++++++++++++++++++++++++++++++++++>-]>++[<+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>-]>++++[<+++++++++++++++++++++++++++++>-]>+++[<+++++++++++++++++++++++++++++++++++++++++>-]+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>>++++++[<+++++++++++++++++++>-]>++[<+++++++++++++++++++++++++++++++++++++++++>-]>+++++++++++[<+++++++++++>-]>++[<+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>-]>+++++++[<+++++++++++++++>-]+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>>+++++[<+++++++++++++++++++>-]>++++++++[<+++++++++++>-]>++++++[<+++++++++++++++++>-]>+++++++[<+++++++++++++++>-]+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>>++[<+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>-]>+++++[<+++++++++++++++++++>-]>+++++++[<+++++++>-]>++++++++[<+++++++++>-]>+++++[<+++++++++++++++++++>-]>++++[<+++++++++++++>-]>+++++[<+++++++++++++++++++>-]+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>>++++++[<++++++++>-]+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>>+++++++[<+++++++++++++++++>-]>++[<+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>-]>+++++++[<+++++++++++++++>-]>+++++++++[<+++++++++++++>-]>++++++[<+++++++++++++++++>-]>+++[<+++++++++++>-]>+++++[<+++++++++++++++++++>-]>++++++++++[<++++++++++++>-]>++++++[<+++++++++++++++++>-]>+++++++[<+++++++++++++++>-]+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>>++[<+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++>-]>+++++[<+++++++++++++++++++++++++>-]+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.>>++++++[<+++++++++++++++++++>-]<.>>++++++[<+++++++++++++++++++>-]<.>>+++[<+++++++++++++++++++++++++++++++++++++>-]<.>>++++++[<+++++++++++++++++++>-]<.>')
#interp('+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++.')


结果

看样子是古典密码,用埃特巴什码解出来了:

注意前两个单词开头对应密文的,首字母要大写。

结果他妈的差4分钟,比赛结束了!好气好气好烦好烦。

2021-09-19
Contents

⬆︎TOP