HackThisSite - Steganography Mission 6
Challenge
A PNG image is provided. The only hint is
Thank you Leafman. 题目提供了一张 PNG 图片,唯一的提示是Thank you Leafman(感谢 Leafman)。
数据文件在
https://www.hackthissite.org/missions/stego/lvl/stego6.png,是一个
100x100 的 RGBA PNG。
Solution
Step 1: 文件类型与容器结构
file 只认出这是 100x100 的 8-bit RGBA PNG,共 1965
字节:
1 | $ file stego6.png |
PNG 是块(chunk)结构,先用 pngcheck -v
走一遍每个块:
1 | $ pngcheck -v stego6.png |
结构很干净:IHDR、一个背景色块 bKGD、一个时间戳块 tIME、一个
IDAT、IEND。bKGD 和 tIME
都是普通元数据,没有藏东西。唯一的异常是最后一行:IEND
之后还有数据。
IEND 是 PNG 的结束标记,规范上文件到它就结束。这里 IEND 块结束于偏移
0x751,而文件长 0x7AD,即后面多出 92
字节。pngcheck 把声明结束点之后还有字节直接报告成 ERRORS
DETECTED。
Step 2: 排除图像内部的隐写
PNG 隐写的另一条常见路径是把数据写入 IDAT
解码后的像素位平面(LSB)。用 zsteg -a
扫全部通道、全部位平面:
1 | $ zsteg -a stego6.png | tr '\r' '\n' | sed '/^[[:space:]]*$/d' | head -n 12 |
(zsteg -a 的原始输出用 \r 分隔通道,这里用
tr 归一化成每行一个通道再看。)
所有 bN,channel,lsb/msb 位平面要么为空,要么只是
text: ["U" repeated 21 times]
这类单字符重复的噪声(那是图像本身大色块的规律,不是文本),没有一处读出可读字符串。第
2 行 chunk:0:IHDR 是 zsteg 把 IHDR 头字节误认成 Photoshop
色板,与本题无关。zsteg 唯一有效的一行是
extradata:0:IEND 之后的 92
字节额外数据,内容是 Base64 文本。
Step 3: 提取 IEND 之后的附载
定位 IEND 块结束的位置,取出后面的字节:
1 | #!/usr/bin/env python3 |
运行结果:
1 | $ uv run python extract_payload.py stego6.png |
Base64
解出来是一句英文:Not like it's hard to 'decrypt' this huh? The password is hgbvZw07.。提示语里的
decrypt 实际是 Base64
解码(编码不是加密),密码就在这句话末尾。
Step 4: Submit
playit 型关卡的提交契约:formkey
每次加载关卡页都会变,所以取页面与提交必须在同一次运行里完成;POST 到
/missions/stego/template.php 时必须带
Referer: <关卡页>,否则模板回
Invalid Referer 且不计分。答案大小写敏感。会话 cookie
从环境变量 HTS_COOKIE 读取,不落盘:
1 | #!/usr/bin/env python3 |
运行输出:
1 | $ cd <hts-workspace>/challenges/hts-stego/6 && uv run python solve.py |
接受后 profile 的 Stego: 行计入 (6)。playit
关卡的响应正文里没有 wrong/correct
之类关键词,不能靠关键词判断,可靠判据是 profile 的类别计数出现
(6)。
Key points
- 判据是 PNG 的声明结束点与实际长度之差:IEND
块结束于
0x751,文件长 1965 字节,多出的 92 字节就是附载。file/binwalk只看魔数,看不出这段附载;pngcheck -v会把它报成additional data after IEND chunk。 - IEND 在合法 PNG 里是唯一的,
data.find(b"IEND") + 8就能定位图像流的终点;不需要遍历块结构。 - 图像内部(IDAT 解码后的所有通道位平面)是噪声,
zsteg -a全部位平面无有效文本;附载只在 trailer 里。zsteg的extradata行会直接给出 trailer,是快速定位手段。 - 附载是纯 ASCII 的 Base64 文本,先按字节读出来再
base64.b64decode;提示里的decrypt是障眼法,实际只是编码不是加密。 - playit 提交纪律:
formkey每次加载都变,必须取页面 → 立刻提交;提交必须带Referer: <关卡页>,否则不计分。