01(矩阵二维码+兽音编码)
题目信息
题目目录下有两个关键文件:
hint.txtflag.zip
flag.zip 中包含加密文件 flag.txt,需要先找到压缩包密码。
1. 分析 hint.txt
打开 hint.txt 后可以看到 25 行由 0 和 1 组成的内容:
1111111011111001001111111
1000001000000001101000001
1011101000100010101011101
...
1111111000010001000011011每行长度都是 25,因此可以判断它是一个 25 x 25 的黑白矩阵。25 x 25 对应 QR Code Version 2。
把 1 作为黑色,0 作为白色渲染后,可以得到一个二维码。
解码二维码,内容为:
p@ssw0rd!所以压缩包密码是:
p@ssw0rd!2. 解压 flag.zip
使用上一步得到的密码解压 flag.zip,得到 flag.txt。
解压出的内容不是明文 flag,而是一串由 ~、呜、喵、啊 组成的文本:
~呜喵喵喵喵呜啊喵啊呜呜喵呜呜~喵喵~啊喵啊呜喵喵...3. 识别兽音编码
这类文本是常见的“兽音译者”编码。
其特征是:
字符集通常只有 4 个字符
本题使用的是
喵、呜、啊、~文本以
~呜喵开头文本以
啊结尾
兽音译者的解码逻辑大致如下:
去掉头部
~呜喵去掉末尾
啊每两个兽音字符表示一个 4-bit 数据
按动态偏移还原 nibble
每 4 个 nibble 还原一个 Unicode 字符
本题使用的字符顺序为:
喵 呜 啊 ~解码脚本如下:
import zipfile
with zipfile.ZipFile("flag.zip") as zf:
s = zf.read("flag.txt", pwd=b"p@ssw0rd!").decode("utf-8")
dict_chars = "喵呜啊~"
prefix = "~呜喵"
suffix = "啊"
body = s[len(prefix):-len(suffix)]
idx = {ch: i for i, ch in enumerate(dict_chars)}
nibbles = []
offset = 0
for i in range(0, len(body), 2):
pair = body[i:i + 2]
val = (idx[pair[0]] << 2) | idx[pair[1]]
n = (val - offset) & 0xF
nibbles.append(n)
offset += 1
plain = ""
for i in range(0, len(nibbles), 4):
code = (
(nibbles[i] << 12)
| (nibbles[i + 1] << 8)
| (nibbles[i + 2] << 4)
| nibbles[i + 3]
)
plain += chr(code)
print(plain)运行后得到:
flag{8a8c0a039c3bd6fb50e84b047e42e8e6}Flag
flag{8a8c0a039c3bd6fb50e84b047e42e8e6}
颜色换成非白色显现第一部分flag
全选文本点击字体,选择文字->取消隐藏出现第二部分flag
改文件后缀为zip
解压之后在word文件夹下发现存在txt,打开第三部分flag

Flag:flag{I_be1ieve_y0u_Can_flnd_+h3m}