隐写技巧——PNG 文件中的 LSB 隐写
0x00 前言
上篇对 PNG 的文件格式进行了分析,介绍了如何在不影响 PNG 文件的正常浏览下将 payload 以辅助数据块 tEXt 的格式插入到 PNG 文件中。这次将要介绍一个在图像数据块 IDAT 下隐藏 payload 的技巧——LSB 隐写
图片引用自 http://datagenetics.com/blog/march12012/index.html
0x01 简介
IDAT 数据块
- 储存图像像数数据
- 在数据流中可包含多个连续顺序的图像数据块
- 采用 LZ77 算法的派生算法进行压缩
- 可以用 zlib 解压缩
zlib 解压缩的 python 实现代码如下:
#! /usr/bin/env python
import zlib
import binascii
IDAT = "789C5D91011280400802BF04FFFF5C75294B5537738A21A27D1E49CFD17DB3937A92E7E603880A6D485100901FB0410153350DE83112EA2D51C54CE2E585B15A2FC78E8872F51C6FC1881882F93D372DEF78E665B0C36C529622A0A45588138833A170A2071DDCD18219DB8C0D465D8B6989719645ED9C11C36AE3ABDAEFCFC0ACF023E77C17C7897667".decode('hex')
result = binascii.hexlify(zlib.decompress(IDAT))
print result
引用自 http://drops.wooyun.org/tips/4862
LSB 隐写
- LSB 全称 least significant bit,最低有效位
- PNG 文件中的图像像数一般是由 RGB 三原色(红绿蓝)组成,每一种颜色占用 8 位,取值范围为 0x00~0xFF,即有 256 种颜色,一共包含了 256 的 3 次方的颜色,即 16777216 种颜色
- 人类的眼睛可以区分约 1000 万种不同的颜色
- 这意味着人类的眼睛无法区分余下的颜色大约有 6777216 种
- LSB 隐写就是修改 RGB 颜色分量的最低二进制位(LSB),而人类的眼睛不会注意到这前后的变化
- 每个像数可以携带 3 比特的信息
0x02 Python 实现
关于 LSB 隐写在 github 上值得学习的项目:
下面对 cloacked-pixel 进行测试
测试图片:
源文件下载地址: http://www.easyicon.net/language.en/1119182-Enderman_Png_icon.html
1、 加密
运行:
python lsb.py hide big.png 1.txt 123456
参数说明:
hide:表示加密模式 big.png:待加密的 png 图片 1.txt:存放 payload 123456:加密的密码
运行后生成图片 big.png-stego.png
如图
分析一下加密图片 big.png-stego.png 的格式,使用上篇文章介绍的 check.cpp
下载地址:https://github.com/3gstudent/PNG-Steganography/blob/master/check.cpp
加密前后对比如图
cloacked-pixel
在加密的过程中会删除其他数据块,只保留关键数据块 IDAT
使用 HexEditorNeo
查看加密图片也能印证我们的判断,如图
注:当然也可以通过阅读源码进行分析
2、 解密
运行:
python lsb.py extract big.png-stego.png 3.txt 123456
参数说明: extract:表示解密模式 big.png-stego.png:待解密的 png 图片 3.txt:存放导出的 payload 123456:解密密码
如图,成功解密获得 payload
3、 分析
运行:
python lsb.py analyse big.png-stego.png
参数说明:analyse:表示分析模式 big.png-stego.png :待分析的 png 图片 运行后会对图像进行分析,将其分割成块,标记每个块的最低有效位
如图
这是加密前后分析对比图
肉眼几乎无法分辨图片的差别,因为 payload 越短,分析图的差别就越小,这里我们可以借助软件帮助分析
工具名称:Stegsolve
下载地址:http://www.caesum.com/handbook/Stegsolve.jar
环境搭建:
安装 jdk,配置 java 环境
使用 Stegsolve
打开 a.png,选择 Analyse-Image Combiner,选择 b.png
进行 异或对比(XOR)
,如图,检测到细微的差异
0x03 C++实现
Grant Curell
分享了通过 c++实现的方法,值得学习,所以在此对其介绍并进行测试
文章地址: http://www.codeproject.com/Articles/581298/PNG-Image-Steganography-with-libpng 作者:Grant Curell
代码下载链接:http://www.codeproject.com/KB/security/581298/PNG_stego.zip
测试环境:
Win7 X64
vs2012
1、 直接编译会报错
项目 zlib
可直接编译成功
编译项目 libpng
,错误如下:
fatal error C1083: Cannot open include file: 'zlib.h': No such file or directory
解决方法:
需要对项目添加 include 目录
右键-Property-VC++ Directories
选择 Include Directories
如图
添加 zlib-1.2.3,输入:
..\..\..\zlib-1.2.3;
如图
再次编译,报错如下:
fatal error LNK1181: cannot open input file 'zlib.lib'
解决方法:
需要对项目添加 lib 目录
选择 Library Directories
添加 zlib.lib,输入:
..\..\..\LIB Debug;
如图,编译成功
Tips:
在 Include Directories 和 Library Directories 中也可以直接指定绝对路径(如 C:\test\cloacked-pixel-master\PNG_stego\zlib-1.2.3),本例使用 ..\
表示的是相对路径
编译项目 PNG_encode_decode
,发生同样的编译错误
解决方法:
Include Directories 下添加 zlib-1.2.3 和 libpng-1.2.37-src,输入:
../zlib-1.2.3;../libpng-1.2.37-src;
Library Directories 下添加 libpng.lib,输入:
..\LIB Debug;
如图,最终编译成功
注:三个项目工程存在前后的调用关系,所以编译顺序为 zlib
- libpng
- PNG_encode_decode
2、 加密测试
待加密文件:big.png
payload 文件:1.txt
输出加密文件:bigen.png
项目 PNG_encode_decode
中的 main.cpp 修改如下:
#include "PNG_file.h"
void main() {
PNG_file link = PNG_file("big.png");
link.encode("1.txt");
link.outputPNG("bigen.png");
}
运行后生成 bigen.png
,如图
对比加密前后的文件,大小存在差异,如图
原理上 LSB 隐写不会改变文件大小,查找原因
使用 check.cpp
解析数据块目录,发现加密后多了数个 tTXt 段
如图
使用 HexEditorNeo 查看加密图片细节,如图
加密后的图片包含了原图片的一些信息,造成了图片大小不同
3、 去掉多余信息
方法 a:
使用 HexEditorNeo
直接删除多余信息
方法 b:
使用 compress.cpp
下载地址:
https://github.com/3gstudent/PNG-Steganography/blob/master/compress.cpp
生成去掉多余 tTXt 段的加密图片 bigensimple.png
,如图
bigensimple.png 同原图片大小相同,如图
4、 解密测试
项目 PNG_encode_decode
中的 main.cpp 修改如下:
#include "PNG_file.h"
void main() {
PNG_file link = PNG_file("bigensimple.png");
link.decode("2.txt");
}
运行后生成 2.txt,获得存储加密后的 payload
(5) 分析
对于 LSB 隐写,可使用 Stegsolve
辅助分析
打开加密图片后,选择 Analyse-DataExtract
Bit Planes 选中 Reg、Green、Blue 的第 0 位
Bit Order 选中 LSB First
Bit Plane Order 选中 RGB
可以看到加密形式的 payload,如图
注: 当然可以通过阅读程序源码找到图片的加密数据,本例只是给出对图片分析的一些参考思路
0x04 小结
本文分别介绍如何通过 Python 和 C++实现对 PNG 文件的 LSB 隐写,参照文中的分析思路也可对常见的 LSB 隐写数据进行提取分析。
注:修改好的 PNG_stego 工程已上传至 github:https://github.com/3gstudent/PNG_stego-test
更多学习资料:
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: 隐写技巧——利用 PNG 文件格式隐藏 Payload
下一篇: Covenant 利用分析
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论