CTF隐写术(图片隐写)
附加式的图片隐写:
字符串方式:
字符串附加在文件的后面是因为,如果图片附加在中间,可能破坏图片的信息;如果附加在图片的头部位置,又破坏了文件头。基于此点,也可以使用16进制编辑器找到这一串字符串。
分离方法:
- strings分离:
-a --all
:扫描整个文件而不是只扫描目标文件初始化和装载段
-f –print-file-name
:在显示字符串前先显示文件名
-t --radix={o,d,x}
:输出字符的位置,基于八进制,十进制或者十六进制
-e --encoding={s,S,b,l,B,L}
:选择字符大小和排列顺序:s = 7-bit, S = 8-bit, {b,l} = 16-bit, {B,L} = 32-bit
分离命令:(cmd)
strings xxx.jpg
使用WinHex查看图片源码或查看图片属性。
图种方式:
图片后缀:
将图片后缀名改为.zip\rar\7z
等压缩格式后打开。
图片拼接:
以cmd命令行copy /b 1.jpg+2.jpg 3.jgp
以二进制方式连接两个图片。
分析方法:
使用binwalk工具分析图片,可以发现从35786块偏移开始有另一张jpg图片。(win下安装binwalk:python setup.py install
):
C:\Python27\Scripts>python binwalk 3.jpg
分离方法:
- 一是使用WinHex分离:
jpg格式文件开始的2字节是FF D8,之后2个字节是FF E0 ,最后2个字节是图像文件结束标记为FF D9 。我们打开3.jpg,Alt+A全选图片16进制数值,菜单—搜索—十六进制数值—填入FFD8—取消统计次数—勾选列出搜索结果,定位到第二个FFD8处(或使用Alt+G快捷键定位到35786处),使用Alt+1快捷键选取FF为开始块,Alt+2选取D9为结束块,然后右键—Edit—Copy Block—Into New File保存.jpg后缀的文件。得到隐藏图片:
- 二是使用foremost分离:
foremost是一个基于文件文件头和尾部信息以及文件的内建数据结构恢复文件的命令行工具。
分离命令:
foremost xxx.jpg
会自动生成output目录存放分离出文件。
文件拼接:
使用命令 copy /b 1.jpg + 1.zip 2.jpg
,利用copy命令将两个文件以二进制方式连接起来。在jpg中结束符是FF D9,图片查看器会忽视jpg结束符之后的内容,所以附加的zip不会影响到图像的正常显示。
分离方法:
- 一是使用WinHex分离:
50 4B 03 04就是ZIP文件的文件头,一般以PK表示。
选取以50开头以及到末尾的的数据,右键单击,选择编辑,复制选块到新文件,保存新文件为zip格式命名规则即可。
- 二是使用foremost分离:
具体操作同上。
基于文件结构的图片隐写:
PNG图片结构:
标准的PNG文件结构包括:PNG文件标识和PNG数据块。
PNG图片文件结构:
(固定)8字节89 50 4E 47 0D 0A 1A 0A为png文件头;
(固定)4字节00 00 00 0D(即十进制的13)代表数据块的长度为13;
(固定)4字节49 48 44 52(即为ASCII码的IHDR)是文件头数据块的标识(IDCH);
(可变)13位数据块(IHDR)
前四个字节代表该图片的宽
后四个字节代表该图片的高
后五个字节依次为:
Bit depth、ColorType、Compression method、Filter method、Interlace method
(可变)剩余四字节为该png的CRC检验码,由从IDCH到IHDR的十七位字节进行crc计算得到。
PNG图片文件头数据块(IHDR)包括:宽、高、图像深度、颜色类型、压缩方法等(图中蓝色的部分即IHDR数据块)。
修改高度隐写:
先用TweakPNG打开图片,一般修改过长宽的图片都会报错。
找到PNG图片高度值所对应的位置,并修改为一个较大的值,尝试打开。
修改01 00为02 00,并保存后打开。
修改宽高之后的PNG图片可能打不开,需要修复PNG图片的CRC校验值。
方法:
选中PNG的struct IHDR Ihdr部分(图中蓝色部分),使用CRC Calculator重新计算CRC校验值。
将struct IHDR Ihdr的CRC(图中蓝色部分)修改为重新计算过的CRC。
再用TweakPNG打开图片不报错,修复成功。
IDAT块的隐写:
PNGCheck可以验证PNG图片的完整性(通过检查内部CRC-32校验和&bra;比特&ket;)和解压缩图像数据,它能够转储几乎所有任选的块级别信息在该图像中的可读数据。
查询命令:
pngcheck -v xxx.png
基于LSB原理的图片隐写:
简单的LSB隐写:
利用LSB(最低有效位 (Least Significant Bit)来进行隐写。例如在PNG图片的储存中,每个颜色会有8bit,LSB隐写就是修改了像数中的最低的1bit,人眼无法区别。例如我们想把A隐藏进来的话,可以把A转成16进制的0x61再转成二进制的01100001,再修改为红色通道的最低位为这些二进制串。
分离方法:
- Stegsolve分离:
使用Stegsolve—Analyse—Frame Browser,可以浏览三个颜色通道中的每一位。
此种隐写的载体一般为png或bmp格式,jpg的有损压缩方式会破坏隐写的内容。
基于DCT域的JPG图片隐写:
背景知识:
JPEG图像格式使用离散余弦变换(Discrete Cosine Transform,DCT)函数来压缩图像,而这个图像压缩方法的核心是:通过识别每个8×8像素块中相邻像素中的重复像素来减少显示图像所需的位数,并使用近似估算法降低其冗余度。因此,我们可以把DCT看作一个用于执行压缩的近似计算方法。
因为丢失了部分数据,所以DCT是一种有损压缩(Loss Compression)技术,但一般不会影响图像的视觉效果。
在这个隐写家族中,常见的隐写方法有JSteg、JPHide、Outguess、F5等等,分离方法为Stegdetect。
Stegdetect简介:
Stegdetect可以检测到通过JSteg、JPHide、OutGuess、Invisible Secrets、F5、appendX和Camouflage等这些隐写工具隐藏的信息,并且还具有基于字典暴力破解密码方法提取通过Jphide、outguess和jsteg-shell方式嵌入的隐藏信息。
Stegdetect参数:
- -q 仅显示可能包含隐藏内容的图像。
- -n 启用检查JPEG文件头功能,以降低误报率。如果启用,所有带有批注区域的文件将被视为没有被嵌入信息。如果JPEG文件的JFIF标识符中的版本号不是1.1,则禁用OutGuess检测。
- -s 修改检测算法的敏感度,该值的默认值为1。检测结果的匹配度与检测算法的敏感度成正比,算法敏感度的值越大,检测出的可疑文件包含敏感信息的可能性越大。
- -d 打印带行号的调试信息。
- -t 设置要检测哪些隐写工具(默认检测jopi),可设置的选项如下:
- j 检测图像中的信息是否是用jsteg嵌入的。
- o 检测图像中的信息是否是用outguess嵌入的。
- p 检测图像中的信息是否是用jphide嵌入的。
- i 检测图像中的信息是否是用invisible secrets嵌入的。
- -V 显示软件版本号。
Stegdetect会在检测结果后面使用1~3颗星来标识隐藏信息存在的可能性大小,3颗星表示隐藏信息存在的可能性最大。
Stegdetect命令(cmd):
stegdetect.exe -tjopi -s 100.0 xxx.jpg
JPHS提取:
使用Stegdetect探测jpg隐藏种类。
使用JPHS打开图片,点击Seek功能,会弹出一个密码的输入框,这里默认为空口令,点击OK,将提取出来的信息保存为flag.txt。
Outguess提取:
使用Stegdetect探测jpg隐藏种类。
点击Enter key功能,输入密码,这里我隐写的时候,使用的密码是123456
点击Load image 加载目标图片
点击Extract file功能,将提取出来的信息保存成flag.txt文件。
数字水印的隐写:
背景知识:
数字水印:
数字水印(digital watermark)技术,是指在数字化的数据内容中嵌入不明显的记号。
特征是,被嵌入的记号通常是不可见或不可察的,但是可以通过计算操作检测或者提取。
盲水印与傅里叶变换:
盲水印,是指人感知不到的水印,包括看不到或听不见(没错,数字盲水印也能够用于音频)。其主要应用于音像作品、数字图书等,目的是,在不破坏原始作品的情况下,实现版权的防护与追踪。
对图像进行傅里叶变换,起始是一个二维离散傅里叶变换,图像的频率是指图像灰度变换的强烈程度,将二维图像由空间域变为频域后,图像上的每个点的值都变成了复数,也就是所谓的复频域,通过复数的实部和虚部,可以计算出幅值和相位,计算幅值即对复数取模值,将取模值后的矩阵显示出来,即为其频谱图。但是问题来了,复数取模后,数字有可能变的很大,远大于255,如果数据超过255,则在显示图像的时候会都当做255来处理,图像就成了全白色。因此,一般会对模值再取对数,在在0~255的范围内进行归一化,这样才能够准确的反映到图像上,发现数据之间的差别,区分高频和低频分量,这也是进行傅里叶变换的意义。
2. 频域盲水印隐写:
分离方法:
- Blind-watermark(python 2.7):
分离水印命令:
python decode.py --original <original image file> --image <image file> --result <result file>
添加水印命令:
python encode.py --image <image file> --watermark <watermark file> --result <result file>
图片容差隐写:
背景知识:
容差,在选取颜色时所设置的选取范围,容差越大,选取的范围也越大,其数值是在0-255之间。
容差比较的隐写:
分离方法:
操作步骤:
打开工具,选择图片比较,导入example_1.jpg和example_2.jpg。
选择容差模式,并调整容差大小
二维码隐写:
QR Research解码:
使用QR Research读取二维码中的信息。
python脚本生成二维码:
使用python脚本,10组合的将字符串解码成flag.png。