本章目录(9)On this page (9)
  1. 先做三件不用工具的事
  2. 追加型:文件尾挂文件
  3. LSB:最低有效位
  4. 密码型:steghide
  5. EXIF 与其他元数据
  6. 图片本身的信息
  7. 音频也可以
  8. 一个提醒
  9. 参考
文章Articles

图片隐写

从 copy /B 到 zsteg,Misc 题里最稳的一类,也是最容易一步到位的一类。

更新Updated 2026.10.25securityctfmiscstego

先做三件不用工具的事

拿到一张图,别急着上工具。

  1. file 看真实类型。后缀是 .jpg,实际是 PNG 或者 ZIP 的情况很常见。
  2. strings 看一眼。flag 直接写在里面的事,每年都有。
  3. 看文件大小。几十 KB 的图几 MB 大,后面肯定挂了东西。

这三步花不到一分钟,能解决相当一部分题目。

追加型:文件尾挂文件

最简单的一种:在图片末尾追加一段数据。

copy /B a.gif+b.txt out.jpg      # Windows
cat a.gif b.txt > out.jpg        # Linux

图片查看器只读到自己该读的位置就停,后面的数据不影响显示。

还原:找文件结束标记。PNG 是 IEND 后面,JPEG 是 FFD9 后面,GIF 是 3B 后面。用 binwalk 能自动识别并分离:

binwalk -e out.jpg

LSB:最低有效位

把数据藏在像素值的最低位。改一个像素的 RGB 最低位,人眼看不出区别,但信息就在里面。

zsteg image.png              # 自动试各种位平面和通道组合
zsteg -a image.png           # 试全部

zsteg 只支持 PNG 和 BMP,因为 JPEG 是有损压缩,改最低位会被压没。

手工提取的话,读每个像素的 R 通道最低位,拼成比特流,再按 8 位转字符。这个流程写一遍就懂了。

密码型:steghide

steghide 把数据加密后嵌进 JPEG,需要密码才能取。

steghide embed -cf a.jpg -ef secret.txt     # 嵌入
steghide extract -sf a.jpg                  # 提取,会问密码

密码从哪来?题目里通常有提示:图片文件名、EXIF 信息、题目描述里的一句话。

空密码也值得试一次——很多人嵌的时候没设密码。

EXIF 与其他元数据

exiftool image.jpg

Comment、Artist、Copyright、GPS 这些字段都可能藏东西。有的题目把 flag 拆成几段放在不同字段里。

图片本身的信息

有些题不在文件里藏东西,而是图片内容本身就是密文:

  • 二维码。扫一下,或者用 zbarimg。二维码被裁掉一角、加了噪点、反色的情况都有,得手工修。
  • 像素级编码。把图片放大到像素级,每个像素代表一个比特。常见的是黑白两色图。
  • 调色板。PNG 的调色板顺序被打乱,按索引还原。
  • 宽高被改过。PNG 的 IHDR 里宽高被改小,图片下面一截看不到。用脚本改回正确高度,或者用 pngcheck 看 CRC 对不对。

最后这条很典型:pngcheck -v image.png 报 CRC 错误,说明 IHDR 被改过。按文件大小反推正确高度:

height = (文件大小 - 头部开销) / (宽度 × 每像素字节数)

音频也可以

同类的还有音频隐写:频谱图里画字(用 Audacity 看 Spectrogram)、摩斯码、LSB。

看到 .wav 就先看频谱图,这条几乎成了条件反射。

一个提醒

隐写题的难点通常不在技术,在判断该用哪种方法。

我的顺序是:看文件类型 → 看大小 → strings → binwalk → zsteg / steghide → EXIF → 像素级。

从便宜的往贵的试,别一上来就写脚本。

参考

  • 《一文玩转图片的隐写》,公众号存档