Misc + 黑白琴弦

解题思路(必须包含文字说明+截图)

1. 基础信息

题目附件解开后得到 21 张条码图和一个加密的 `score.rar`。题目名称“黑白琴弦”提示信息藏在图像的黑白数据层中,而不是常规文本提示。

2. 三路信息提取

先提取每张 PNG 的可见 Code128 文本和 PNG Comment,可以恢复出两批 8 字符字符串,其中部分命中固定格式“字母 + 6 位十六进制 + 同字母”。

继续分析图像本体后,发现顶行像素的 R 通道 LSB 还藏着第三路数据。按“顶行、R 通道、LSB、正向、offset 0”提取后,又恢复出另外 5 行同格式字符串,最终补齐 A 到 U 共 21 行十六进制数据。

最终得到的 21 行数据如下:

A -> 1fd57f

B -> 104641

C -> 17595d

D -> 175b5d

E -> 17535d

F -> 104e41

G -> 1fd57f

H -> 000300

I -> 1e5e9d

J -> 11a71f

K -> 05c8cf

L -> 0aac3a

M -> 0057fe

N -> 0015c3

O -> 1fcef8

P -> 104d8f

Q -> 174f3e

R -> 175556

S -> 1753cc

T -> 105ac1

U -> 1fddc8

3. 还原二维码矩阵

将 A..U 按字母排序,每行 6 位十六进制转成 24 位二进制。因为二维码只需要 21 列,所以枚举每行裁掉 3 位的 4 种起点,同时尝试反色、旋转和镜像组合,再用 OpenCV 的 `QRCodeDetector` 解码。

最终在 `crop_start=3`、反色、原向的组合上识别出二维码内容:

`TvUiXMI1vohhtVf`

4. 解压 `score.rar`

使用二维码内容 `TvUiXMI1vohhtVf` 成功解压 `score.rar`,得到:

`music score.pdf`

说明二维码结果就是压缩包密码。

5. 提取乐谱提示

从 PDF 文本层可以直接抽到提示:

`KEY+bnVtYmVyYWJvdmVsaW5l3`

将 `bnVtYmVyYWJvdmVsaW5l` 进行 Base64 解码,得到:

`numberaboveline`

因此提示含义为:

`KEY + 第 3 行上方的数字`

查看乐谱第 3 行后,可以读出上方数字为:

`4151515`

所以最终 flag 为:

`ISCC{TvUiXMI1vohhtVf4151515}`

6. 验证

先验证 `TvUiXMI1vohhtVf` 能正确解开 `score.rar`,再结合 PDF 提示和第 3 行数字 `4151515` 拼接出完整 flag。

Exp(如有,请粘贴完整代码,不允许截图!)


from PIL import Image

import cv2

import numpy as np

rows = {

'A': '1fd57f',

'B': '104641',

'C': '17595d',

'D': '175b5d',

'E': '17535d',

'F': '104e41',

'G': '1fd57f',

'H': '000300',

'I': '1e5e9d',

'J': '11a71f',

'K': '05c8cf',

'L': '0aac3a',

'M': '0057fe',

'N': '0015c3',

'O': '1fcef8',

'P': '104d8f',

'Q': '174f3e',

'R': '175556',

'S': '1753cc',

'T': '105ac1',

'U': '1fddc8',

}

bitrows = [bin(int(rows[k], 16))[2:].zfill(24) for k in sorted(rows)]

qrd = cv2.QRCodeDetector()

for crop_start in range(4):

mat = [[1 if b == '1' else 0 for b in row[crop_start:crop_start+21]] for row in bitrows]

arr = np.array(mat, dtype=np.uint8) * 255

img = 255 - arr

data, _, _ = qrd.detectAndDecode(img)

if data:

print(data) # TvUiXMI1vohhtVf

Flag:`ISCC{TvUiXMI1vohhtVf4151515}`