问题链接:https://buuoj.cn/challenges#洞拐洞拐洞洞拐
问题附件是一张图片。
一. 图片分析
查看图片,发现是由有规律的黑白像素构成的PNG图片,用Python脚本尝试以黑色为1,白色为0分别按行读取,发现00xxxxxx00.......的规律,按照char 型读取,发现都是可打印字符,读取及转换代码如下:
#使用:.\hb黑白像素块10.py 2239f085-4e8c-425b-9e8e-793c982c42f5.png
#author:CHTXRT
from PIL import Image
import sys
img = Image.open(sys.argv[1])
temp = ''
n = 0
for x in range(320):
for y in range(320):
n+=1
if(img.getpixel((x,y))==(255,255,255)):
temp += '0'
else:
temp += '1'
if(n==8):
n = 0
print(chr(int(temp,2)),end='')
temp = ''
img.close()
得到结果:
52494646FC18000057415645666D742010000000010001000A000000140000000200100064617461D8........(以下省略n行)
二. 音频分析
上边那串数据看起来像个文件,把它扔到编辑器里面,发现 .wav文件头。
![](https://i-blog.csdnimg.cn/blog_migrate/e05dc9a0c4f1ba164da427f684f4a232.png)
改名2333.wav 保存,用Audacity 打开如图所示:
![](https://i-blog.csdnimg.cn/blog_migrate/2880a910910ed98a12a9f9e65e38441a.png)
是个单声道音频(important),观察音频,列出部分音阶:
-0.5 -0.5 0.5 -0.5 0 -0.25 -0.5 -0.25 1.0 -0.5 -0.75 ......(以后省略n项)
发现每段只有 8 种可能:-0.75 -0.5 -0.25 0.0 0.25 0.5 0.75 1.0
盲猜一波八进制,转换前半部分得到 115132127107 ,如果按3个拆分,可以得到 77 90 87 71 ,都属于Ascii 可打印字符,用Python 脚本进行转换,代码如下:
#使用:.\wv音频处理.py 2333.wav
#author: CHTXRT
import sys
import wave
import struct
wav = wave.open(sys.argv[1],'r')
frame = wav.getnframes()
data = wav.readframes(frame)
h = [0]*(len(data)//2)
for i in range(len(data)//2):
h[i] = (struct.unpack('<h',data[i*2:i*2+2]))[0]
hmax = 32767
temp = ''
for i in range(0,len(h),10):
temp += str(round(h[i]/hmax*4)+3)
if(len(temp)==3):
print(chr(int(temp,8)),end='')
temp = ''
#其中 wave 转换采用的相关 wav 格式知识见下文第四节。
得到一段数据如下:
MZWGCZ33G44GGNRTHE3DEMZSGQ4TQMZQMY2WCNRZGZSDCOBYHBRGMMZUMFSWIMZSGVRTQY3DGIZWIZDBO5SDKML2PJYXUMRTGMZTGYLBPU
三. 编码分析
上边那段文字看起来像段密文,如果是做题做多了或者熟悉Base系列的同学可能会一眼盯真,看出前四个字正是flag的 Base32 编码,不熟悉的同学可以使用相关枚举脚本查看(懒得写了,以后可能补),解密明文如下:
flag{78c639623249830f5a696d1888bf34aed325c8cc23ddawd51zzqz23333aa}
四. wav 分析
本节作为补充知识,勉强算是我在编写上述脚本时学习的记录吧。
对于 wav 文件来说,它的音频由许多采样点构成,每个采样点占用 2 或 4 个字节(单声道音频就是 2 字节,双声道就是 4 个字节,高八位是左声道,第八位是右声道),每个声道的采样数据是一个短整数(int_8),同时我们还应该着重注意的是,wav 文件的数据是小端存储的,所以我们应该先读后四位,再读前四位 [1]。
#使用:.\wv音频处理.py 2333.wav
#author: CHTXRT
import sys
import wave
import struct
wav = wave.open(sys.argv[1],'r')
frame = wav.getnframes()
data = wav.readframes(frame)
h = [0]*(len(data)//2)
for i in range(len(data)//2):
h[i] = (struct.unpack('<h',data[i*2:i*2+2]))[0] #[1] unpack方法中的第一个参数中,‘<’代表小端存储读取
hmax = 32767
temp = ''
for i in range(0,len(h),10):
temp += str(round(h[i]/hmax*4)+3)
if(len(temp)==3):
print(chr(int(temp,8)),end='')
temp = ''
以上内容仅供参考,水平不高,大佬见笑。