拓冰建站拓冰建站
首页 / 资讯中心 / 正文

CTF 图片隐写实战:GIF 文件格式解析与空间/时间轴隐写分析(ctf-wiki Misc 篇)

文档网络安全教程【免费下载链接】ctf-wikiCome and join us, we need you!项目地址https://gitcode.com/gh_mirrors/ct/ctf-wiki点击查看免费下载导读本文以 ctf-wiki 仓库中的 GIF 隐写文档 为主体系统拆解 GIF 文件从头部到终结器的完整二进制结构并围绕 CTF Misc杂项方向最常见的两类出题思路——空间轴多帧图像拼合隐写与时间轴帧延迟隐写给出基于 ImageMagickconvert/identify与 Python PIL 的完整解题流程。读完本文你将能够独立解析 GIF 的字节级组成、定位每一帧的像素与延迟信息并复现 WDCTF-2017 与 XMAN-2017 两道典型赛题的还原过程。GIF 文件结构从文件头到终结器GIFGraphics Interchange Format自 1987 年87a版与 1989 年89a版发布以来凭借其简单直接的结构与对动画的原生支持一直是 CTF 隐写题的常客。一个 GIF 文件在逻辑上可分为三大组成部分文件头File Header包含 GIF 文件署名Signature与版本号VersionGIF 数据流GIF Data Stream包含控制标识符、图象块Image Block以及其他的一些扩展块文件终结器Trailer标识整个数据流结束的单字节块。整体组成关系如下图摘自 docs/zh-tw/docs/misc/picture/figure/gif.png图中中间的大块图像数据相关模块可以被重复任意次这正是多帧 GIF 动画与一帧藏一图隐写手法的格式基础。下面按顺序解析各组成部分。文件头Header文件头由两个固定字段构成GIF 署名Signature由三个字符GIF组成用于确认一个文件是否为 GIF 格式版本号Version同样由三个字节组成取值只能是87a或89a分别对应 GIF87a 与 GIF89a 两种规范。因此一个合法的 GIF 文件前 6 个字节必然是47 49 46 38 39 61即 ASCII 码GIF89a或47 49 46 38 37 61GIF87a。解题时若用十六进制编辑器打开文件首先即可检查这 6 个字节来判断文件是否被篡改过头部。逻辑屏幕描述符Logical Screen DescriptorLogical Screen Descriptor逻辑屏幕描述符紧跟在 Header 后面它的作用是告诉 decoder解码器图片需要占用的空间。该块大小固定为 7 个字节以 canvas width画布宽度和 canvas height画布高度开始后续字段还包括全局颜色表标志、颜色分辨率、背景色索引与像素宽高比等。这些字段共同描述了整张虚拟画布的属性所有帧都在这个画布上定位与绘制。全局颜色列表Global Color TableGIF 格式既可以拥有global color table全局颜色表也可以针对每个子图片集提供local color table局部颜色表。每个 color table 由一个 RGB 列表组成RGB 即常见的255, 0, 0红色这种三元组形式。全局颜色表对整个文件中的所有图像生效而局部颜色表只对紧跟其后的单幅图像生效且局部颜色表优先级更高。需要留意的是颜色表区域在结构图中属于可选模块虚线框并非每个 GIF 都必须携带。图像描述块Image Descriptor一个 GIF 文件一般包含多个 image。早期的渲染模式通常是把多张图片绘制到一个大的 virtual canvas虚拟画布上而现在更常见的做法是将这些图片集用于实现动画——每一幅子图就是一帧。每个 image 都以一个 image descriptor block图像描述块作为开头这个块固定为 10 字节其字段布局与字节含义如下图摘自 docs/zh-tw/docs/misc/picture/figure/imagesdescription.png以图中示例字节序列2C 00 00 00 00 0A 00 0A 00 00为例各字段含义如下字段字节范围示例值含义Image Separator第 1 字节2C固定标识位值恒为2C标记图像描述块的开始Image Left第 2–3 字节00 00图像左上角在画布中的 X 坐标水平偏移Image Top第 4–5 字节00 00图像左上角在画布中的 Y 坐标垂直偏移Image Width第 6–7 字节00 0A图像宽度0x0A 10 像素Image Height第 8–9 字节00 0A图像高度0x0A 10 像素Packed Field第 10 字节00一个打包字节内含局部颜色表大小、保留位、Sort 标志、Interlace隔行扫描标志与 Local Color Table 标志等图像数据Image Data图像数据是图片像素实际存储的地方。Image Data 由一系列的**输出编码output codes**构成它们告诉 decoder解码器需要在画布上绘制的每个颜色信息这些编码以字节码的形式组织在该块中。在 GIF89a 规范中像素数据采用 LZW 压缩编码解码器需要依据前导的 LZW 最小码长字段与全局/局部颜色表才能将编码流还原为逐像素的颜色索引。文件终结器Trailer该块为一个单字段块用来指示数据流的结束取固定值0x3b即 ASCII 字符;。一个格式完整的 GIF 文件必然以该字节收尾这也是十六进制编辑器中快速判断文件是否被附加了额外尾部数据如附加文件、隐写 payload的重要检查点。空间轴隐写把秘密拆进每一帧由于 GIF 的动态特性文件由一帧帧的图片构成因此每一帧的图片内容以及多帧图片间的组合方式都成了隐藏信息的载体——这就是空间轴隐写信息藏在像素的排布与拼合之中与时间无关。对于需要分离的 GIF 文件可以使用 ImageMagick 的convert命令将其每一帧分割开来。仓库在 docs/zh-tw/docs/misc/picture/file/cake.gif 中提供了如下示例文件$ convert cake.gif cake.png $ ls cake-0.png cake-1.png cake-2.png cake-3.png cake.gif执行后动画的每一帧会被依次导出为cake-0.png、cake-1.png…… 命名规律的独立静态图片便于后续逐帧分析或按某种拼图规则重组。例题实战WDCTF-2017 Misc 3-2WDCTF-2017:3-2打开该 GIF 后思路很清晰将动画分离出的每一帧图片重新合并即可得到一张完整的二维码。该题中动画被切分为 2×2 的四块每一帧只是二维码的一个象限因此需要把四帧按位置拼回原图。仓库中该题的可直接分析文件位于 docs/zh-tw/docs/misc/picture/file/cake.gif参考解法来自 原文档使用 Python PIL 完成拼接from PIL import Image flag Image.new(RGB,(450,450)) for i in range(2): for j in range(2): pot cake-{}.png.format(ji*2) potImage Image.open(pot) flag.paste(potImage,(j*225,i*225)) flag.save(./flag.png)代码逻辑要点如下先创建一张450×450的空白画布Image.new(RGB, (450, 450))与题目中二维码的完整尺寸一致两层循环遍历 2×2 的四个象限ji*2生成帧序号0, 1, 2, 3与convert导出的文件名一一对应Image.paste把每帧贴到画布对应的位置(j*225, i*225)即每个象限大小为225×225最后flag.save(./flag.png)输出拼合后的完整二维码。扫码后得到一串 16 进制字符串03f30d0ab8c1aa5....74080006030908开头03f3是pyc 文件的头Python 字节码文件魔数前缀据此判断隐藏数据是一份编译后的 Python 字节码。将其按 pyc 格式恢复为 Python 脚本后直接运行即可得到 flag。这一步也提示我们GIF 分离出的数据不一定是图片还可能是任意文件类型的字节流需要结合文件头魔数进一步判断。时间轴隐写把秘密藏进帧间隔除了像素本身GIF 文件每一帧间的时间间隔同样可以成为信息隐藏的载体——这就是时间轴隐写。这类题目不关注帧画面内容而关注动画的播放节奏较短的延迟如 10ms与较长的延迟如 20ms可以分别编码为二进制0与1从而把一长串比特流隐藏在逐帧的 delay 字段中。ImageMagick 的identify命令可以清晰打印出每一帧的时间间隔。其-format参数支持多种格式化输出其中%s表示帧序号scene number%T表示帧延迟时间以百分之一秒为单位即 centi-seconds。例题实战XMAN-2017 100.gifXMAN-2017:100.gif仓库在 docs/zh-tw/docs/misc/picture/file/100.gif 中提供了该题文件参考解法来自 原文档首先用identify导出每一帧的序号与延迟$ identify -format %s %T \n 100.gif 0 66 1 66 2 20 3 10 4 20 5 10 6 10 7 20 8 20 9 20 10 20 11 10 12 20 13 20 14 10 15 10观察输出可以推断20与10分别代表二进制0与1。于是提取每一帧的间隔并转化为比特流$ cat flag|cut -d -f 2|tr -d 66|tr -d \n|tr -d 0|tr 2 0 0101100001001101010000010100111001111011001110010011011000110101001101110011010101100010011001010110010101100100001101000110010001100101011000010011000100111000011001000110010101100100001101000011011100110011001101010011011000110100001100110110000101100101011000110110011001100001001100110011010101111101#这条命令链的处理逻辑是cut -d -f 2按空格分隔取出每行的第二个字段即延迟数值tr -d 66删除开头的两个无关帧延迟66通常对应标题帧或暂停帧不参与编码tr -d \n去掉换行符把多行合并成连续序列tr -d 0删除编码为0的20中的数字0……此步配合下一步将2归一化为0实际效果是把20/10两类延迟统一压缩为单比特序列tr 2 0将20映射为比特0。最终得到以0101100001001101...开头的二进制串将其按 8 位一组转为 ASCII 码即可还原出 flag。从比特串前缀01011000 01001101 01000001...对应 ASCIIXMA也可反推验证编码方向正确。需要补充的是这类题也可以直接用脚本按%T值归一化后转字节例如先得到延迟列表再20 → 0、10 → 1后按 8 bit 分组chr(int(bit, 2))本质与命令链等价但更便于调试与处理长序列。相关文件与工具ImageMagick本文两个例题使用的convert分离帧与identify查看帧延迟/注释均来自该工具集是 Misc 图片分析的基础依赖其-format转义符如%s、%T、%c可灵活组合用于提取帧号、延迟、注释等任意元数据Python PIL / Pillow用于程序化拼合帧、读写像素是空间轴隐写题的标准还原手段参考 图片分析简介 中关于像素值转化的更多用法F5-steganography原文档在隐写软件一节提到的 F5 隐写工具属于 JPEG 域隐写方向可用于检测/提取以 F5 方式嵌入 JPEG 的信息与 GIF 隐写形成互补仓库参考文件本题分析所涉及的示例文件与姊妹篇文档均位于 docs/zh-tw/docs/misc/picture/ 目录包括 cake.gif、100.gif 以及同目录下的 jpg.md、png.mdJPEG/PNG 格式解析与隐写手法可对照学习不同图片格式的异同。小结GIF 隐写题可以归纳为两条主线结构线牢记GIF87a/GIF89a文件头、7 字节逻辑屏幕描述符、可选的全局/局部颜色表、10 字节图像描述块、LZW 编码的图像数据与0x3B终结器。任何多余的字节——无论是帧数异常、延迟异常还是尾部附加数据——都可能是隐写入口载体线空间轴看帧内容用convert拆帧、PIL 拼图、魔数识别隐藏文件时间轴看帧延迟用identify -format %s %T提取并做二进制归一化二者覆盖了 GIF 动态格式最常用的两种藏匿方式。掌握上述结构与命令遇到新的 GIF 题目即可快速完成格式体检 → 拆帧/取延迟 → 二进制还原的标准流程这也是 CTF Misc 方向图片隐写的基础功。赞分享文档网络安全教程【免费下载链接】ctf-wikiCome and join us, we need you!项目地址https://gitcode.com/gh_mirrors/ct/ctf-wiki点击查看免费下载相关推荐CTF Wiki隐写术全解图片、音频与流量包分析技巧CTF Wiki隐写术全解图片、音频与流量包分析技巧 隐写术是CTF竞赛中Misc类别常见的考察方向通过在数字载体中隐藏信息而不被察觉。本文系统梳理图片、音文档网络安全教程ImageStrike 项目推荐ImageStrike 项目推荐 1. 项目基础介绍和主要编程语言 ImageStrike 是一款专为 CTFCapture The Flag竞赛中图片隐写网络安全应用安全ImageStrike一站式CTF图片隐写分析工具完全指南ImageStrike一站式CTF图片隐写分析工具完全指南 ImageStrike是一款基于Python和PyQT5开发的CTF图片隐写综合分析工具专为网络网络安全应用安全上一篇Yaklang 项目使用教程下一篇Angular angular/common 运行时错误码深度解析RuntimeErrorCode 编号体系2000–2999与排障指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门