图片隐写
从 copy /B 到 zsteg,Misc 题里最稳的一类,也是最容易一步到位的一类。
先做三件不用工具的事
拿到一张图,别急着上工具。
file看真实类型。后缀是.jpg,实际是 PNG 或者 ZIP 的情况很常见。strings看一眼。flag 直接写在里面的事,每年都有。- 看文件大小。几十 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 → 像素级。
从便宜的往贵的试,别一上来就写脚本。
参考
- 《一文玩转图片的隐写》,公众号存档