CTF-图片隐写

MISC中的一类

Posted by BlackDn on April 3, 2020

“山不让尘,川不辞盈。方寸一张,满纸荒唐。”

前言

稍稍总结了下 MISC 中的图片隐写
这种题目简单起来两三下,难起来要人命
所以我做题主要还是…随缘…

CTF 图片隐写

隐写是 MISC 的一个大头,而图片隐写是隐写里的一个大头
让我们由简至难看看各种图片隐写的类型

1. 属性隐写 / 文件末隐写

这应该是最简单的隐写了
右键 -> 属性 -> 详细信息,查看是否有可用信息
或者将文件用文本编辑器打开,查看末尾是否有可用信息(就是那种看起来很规律没有乱码的那种)

2. LSB 隐写

Least Significance Bits:像素值的最低有效位(最不显著位)。试想 RGB 格式的颜色,仅将最后一位进行修改后色彩的差异
LSB 隐写:即将信息嵌入到图像的最低有效位
通常这种隐写的对象是无损压缩(PNG、BMP 以及音频.wav 等),因为有损压缩会将嵌入的信息破坏导致丢失

解题方法

主要利用 Stagesolve 查看。
简单的 LSB 隐写在 Stagesolve 切换不同的通道就会发现原图片看不见的痕迹(有的是二维码、有的直接给 flag)
稍微复杂点的需要修改通道查看编码信息。可在 Analyse -> Data Extract 查看,往往勾选 Red,Green,Blue 的 0 位(最低位)查看是否有加密的编码存在

3. 图片长宽还原

众所周知,图片基本由长、宽、位深度等组成,有时候图片的长宽被修改,导致部分图片得不到显示
而我们需要将这部分进行还原,从而得到完整的图片
以 png 格式为例,在其文件头 IHDR 中存储许多图片信息,这里简要介绍一下
参考:PNG 文件格式详解

文件头数据块IHDR(header chunk):含有PNG文件中存储的图像数据的基本信息,并要作为第一个数据块出现在PNG数据流中,而且一个PNG数据流中只能有一个文件头数据块
这里主要介绍几个重要的数据域,紧跟IHDR之后,按顺序来的
1. Width:4 bytes,图像宽度,以像素为单位
2. Height:4 bytes,图像高度,以像素为单位
3. Bit depth:1 byte,图像深度。索引彩色图像:1,2,4,8;灰度图像:1,2,4,8,16;真彩色图像:8,16
4. ColorType:1 byte,颜色类型。灰度图像: 1,2,4,8,16;真彩色图像:8,16;索引彩色图像:1,2,4,8;带α通道数据的灰度图像:8,16;带α通道数据的真彩色图像:8,16

解题方法

利用十六进制编辑器查看主要数据域并进行修改

例题

BugKu–MISC-隐写

  1. 下载文件后得到一张图片
  2. 各种方法尝试无解,binwalk 也没发现文件合成(发现 zlib 文件但没啥用,说实话我也不知道 zlib 文件是啥)
  3. hexeditor 打开,发现 Width 和 Height 的数值不等,即图片长宽不等(括号内为 Width 和 Height,IHDR 后四位/八位)
00000000  89 50 4E 47  0D 0A 1A 0A   00 00 00 0D  49 48 44 52                                      .PNG........IHDR
00000010 [00 00 01 F4  00 00 01 A4]  08 06 00 00  00 CB D6 DF                                      ................
00000020  8A 00 00 00  09 70 48 59   73 00 00 12  74 00 00 12                                      .....pHYs...t...
  1. 长宽修改为一致(当然先往大了改),相当于拉长了高度
00000000  89 50 4E 47  0D 0A 1A 0A   00 00 00 0D  49 48 44 52                                      .PNG........IHDR
00000010  00 00 01 F4  00 00 01 F4   08 06 00 00  00 CB D6 DF                                      ................
  1. 回到图片发现下面扩展的图片部分出现了 flag

4. 图片合成

用特定的命令将两张图片或者图片和压缩文件进行合成
如 windows 下的 copy 命令:

copy /b 1.jpg+2.zip output.jpg

上述命令将图片 1.jpg 和压缩文件 2.zip 进行合并,生成了 output.jpg(实际上是将两个文件的代码首尾相连)
由于图片查看器中,遇到了 1.jpg 的文件尾后停止扫描,因此忽视之后的内容,所以 output.jpg 看起来与 1.jpg 无异

解题方法

可利用十六进制编辑器查看,寻找文件尾后是否还有数据,若有则可用 ExtractJPG 进行分离
或者直接用 binwalk 查看并分离,分离方法有多种,不多赘述

例题

BugKu–MISC-啊哒(来源:第七届山东省大学生网络安全技能大赛)

  1. 得到一个 zip 文件,解压得到一张图片
  2. 尝试各种查看,Stagesolve 查看无果,在属性的相机型号中发现一串字符,盲猜 base 编码,解码后得到“sdnisc_2018”,不知道干啥用先放着
  3. 然后扔到 binwalk 发现内合成了一个 zip,拉出来;还有个 flag.txt,不过是空的
kali@kali:~/Desktop$ binwalk -e ada.jpg

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             JPEG image data, JFIF standard 1.01
30            0x1E            TIFF image data, big-endian, offset of first image directory: 8
5236          0x1474          Copyright string: "Copyright Apple Inc., 2018"
218773        0x35695         Zip archive data, encrypted at least v2.0 to extract, compressed size: 34, uncompressed size: 22, name: flag.txt
218935        0x35737         End of Zip archive, footer length: 22
  1. 解压发现需要密码,尝试之前得到的“sdnisc_2018”,成功解压得到 flag

附 1:图片格式

  1. BMP:与硬件设备无关,压缩小,占用空间较大
  2. JPEG:有损压缩格式
  3. GIF:图形交换格式(Graphics Interchange Format)。基于 LZW 算法的无损压缩格式
  4. PBG:便携式网格图形(Portable Network Graphics)。无损压缩
  5. TIFF:标签图像文件格式(Taglmage FileFormat)
  6. PCX:文件头(128Byte)+实际图像数据。利用 PEXREL 技术压缩
  7. TGA:已标记图形(Tagged Graphics)。结构简单
  8. EXIF:可交换图像文件格式(EXchangeable Image file Format)。与 JPEG 格式相同,额外储存日期、光圈、快门等数据,为数码相机图像提供
  9. FPX:闪光照片(Flash Pix)。多重分辨率,放大仍能维持影像素质
  10. SVG:可缩放矢量图形(Scalable Vector Graphics)。基于 XML,可任意放大而不出现锯齿化
  11. PSD:Photoshop 专用图像文件格式,保存图层、蒙版等信息
  12. CDR:CorelDRAW 专用图像文件格式,保存属性、位置、分页等信息
  13. PCD:照片激光唱片(PhotoCD),其他软件只能读取
  14. DXF:图纸交换格式(Drawing eXchange Format):AutoCAD 专用图像文件格式
  15. AI:矢量图形文件,Adobe 出品,与 PSD 类似,保存图层等信息
  16. UFO:Ulead PhotoImapct 专用图像文件格式
  17. EPS:封装式页描述语言(Encapsulated PostScript),跨平台标准格式
  18. RAW:包含图片产生的原生信息(单反高质量图片所采用的格式)
  19. Webp:提供有损压缩和无损压缩,源自 VP8 图像编码
  20. WMF:Windows 中一种矢量文件格式
  21. FLIC:Autodesk 公司研制,FLC 与 FLI 的统称
  22. HDRI:高动态范围成像(High Dynamic Range Imaging)。保存光照信息,记录超出 256 的亮度值,无法在屏幕上显示

常见文件头与文件尾

格式 文件头 文件尾
JPEG(jpg) FFD8FF FF D9
PNG(png) 89504E47 AE 42 60 82
GIF(gif) 47494638 00 3B
ZIP Archive 504B0304 50 4B
TIFF(tif) 49492A00 -
RAR Archive 52617221 -

附 2:图片分离方法

发现这个图片有多个文件合成,有多个方法将其分离
当然不止以下几种,还有很多工具可以做到分离,但是目前这些对我来说够用,就先用着

1. binwalk

利用命令

binwalk -e 文件

-e 表示 extract,可将 binwalk 扫描出的每个文件分离提取
命令执行成功后会在文件的原目录下生成一个文件夹,里面就是提取出的东西了
举个例子 🌰:

kali@kali:~/Desktop$ binwalk -e Welcome_.jpg

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             JPEG image data, JFIF standard 1.01
30            0x1E            TIFF image data, big-endian, offset of first image directory: 8
52516         0xCD24          Zip archive data, at least v1.0 to extract, compressed size: 6732, uncompressed size: 6732, name: flag.rar
59264         0xE780          End of Zip archive, footer length: 22
147852        0x2418C         End of Zip archive, footer length: 22

我们可以看到,数据块 0-30 是图片文件,而数据块 52516 开始是一个 zip 文件
用此命令将其提取,做进一步的解题

2. foremost

利用命令

foremost 文件

和 binwalk -e 类似,会在图文件的原目录目录下生成一个 output 的文件夹
不知道为啥我的 kali 没有自带 foremost,所以我还是习惯用 binwalk

3. dd 命令

利用命令

dd if=source.jpg of=out.jpg

dd 命令可以从 source.jpg 中分理出 out.jpg(名字是自定义的)