一张看似普通的图片提风景照,右键保存到本地,隐藏拖进十六进制编辑器里,信息翻到文件尾部,工具你会发现FFD9结束标记后面还跟着三百多KB的图片提乱码数据。这就是隐藏最朴素的图片隐写——把东西塞在图片"死后"的空间里。图片查看器读到FFD9就停了,信息后面那截它根本不看。工具
我最早接触这类工具是图片提几年前帮一个做取证的朋友打下手。他手里有一批从某论坛扒下来的隐藏图片,怀疑里面夹带了非法交易的信息联络信息。当时我用的工具是`steghide`,命令行敲进去,图片提密码试了十几次,隐藏最后跑出来一段Base64字符串。信息那种感觉怎么说呢,像在墙缝里摸到一张叠得极小的纸条。
图片隐藏信息提取,本质上就两条路:一是找"多出来的数据",二是找"被改过的数据"。
多出来的数据最好找
JPEG文件有明确的起止标记,PNG有IEND块。在这些结构结束之后追加内容,图片照样正常显示。`binwalk`这类工具扫一眼就能看到附加段,甚至不用工具,Linux下`tail -c 500 image.jpg`直接看尾部就行。有些粗心的藏家连加密都懒得做,附加段里就是明文。
EXIF也是重灾区。相机拍的原图会写入GPS坐标、设备型号、拍摄时间,这些是正常元数据。但有人会手动往EXIF的Comment字段或者MakerNote里塞东西。我见过一张图,Comment字段里是一串坐标,对应到某个仓库的位置。`exiftool`一条命令就能拉出来,没什么技术含量,纯粹是藏的人心存侥幸。
改过的数据就麻烦了
LSB(最低有效位)替换是最经典的方案。每个像素的RGB三个通道各有8位,把最低位换掉,肉眼完全看不出色差。一张1920×1080的图,能藏约777KB的数据。提取需要知道嵌入顺序——是按行扫描还是按列,是RGB还是只改R通道,从哪个像素开始。这些参数构成了一把"钥匙",不知道就提取不出来。
更隐蔽的是DCT域隐写。JPEG压缩时会把图像分成8×8块做离散余弦变换,有人在量化后的系数里动手脚。这种改动不会在像素层面留下明显痕迹,但重新保存一次图片就可能把数据毁掉。提取工具得逆向整个JPEG编码流程,复杂度高出一大截。
我自己的习惯是先用`zsteg`扫一遍PNG,再用`steghide`试空密码和常见密码,最后拿`stegsolve`逐通道翻色。三板斧下去,八成以上的图都能出结果。剩下的硬骨头,要么上暴力破解,要么手动分析像素分布找异常。
有个细节值得说:很多人以为提取出来的就是最终答案。实际上经常是套娃。我遇到过提取出一段文本,内容是"密码是下一张图的文件名",然后拿那个密码去解另一张图。还有一次提取出一个压缩包,解压后里面是一张新图,新图里再藏一层。藏的人显然享受这个过程。
工具本身不复杂,Python写个LSB提取器不到五十行代码。难的是判断"这张图有没有问题"。我的经验是看文件大小和分辨率是否匹配。一张1080p的纯色图正常压缩后也就几十KB,如果它有两百KB,那多半有东西。另外,图片反复被转发、截图、压缩后,隐写数据基本就废了。所以真正有价值的隐写图,往往来自原始文件,而不是社交媒体上流传的版本。
这类工具用多了会形成一种直觉:看到一张图,先看大小,再看格式,然后扔进工具跑一遍。大部分时候没收获,但偶尔跑出东西的那一刻,确实让人上瘾。