隐写术实战:从BUUCTF Findme题目,盘点PNG文件中那些藏信息的‘冷门’角落

张开发
2026/4/17 16:16:29 15 分钟阅读

分享文章

隐写术实战:从BUUCTF Findme题目,盘点PNG文件中那些藏信息的‘冷门’角落
隐写术深度解析PNG文件中那些意想不到的信息藏匿点在数字取证和信息安全竞赛中PNG文件一直是隐写术的热门载体。大多数人熟悉LSB最低有效位隐写或文件尾附加数据这类基础技巧但真正的CTF高手知道PNG格式的复杂性为信息隐藏提供了更多冷门角落。本文将带您系统探索这些鲜为人知但经常被出题人利用的藏匿点并通过实际案例展示如何检测和提取这些隐藏信息。1. PNG文件结构基础与隐藏机会PNG便携式网络图形文件远比表面看起来复杂。它由多个数据块chunk组成每个块都有特定的结构和校验机制。理解这些基础结构是发现隐藏信息的第一步。一个标准的PNG文件包含以下关键数据块IHDR块包含图像的基本信息宽度、高度、位深等PLTE块调色板数据仅索引彩色图像需要IDAT块存储实际图像数据IEND块文件结束标记每个数据块的结构如下表所示字段长度(字节)说明Length4数据字段的长度Chunk Type44个ASCII字符标识块类型Chunk Data可变实际数据CRC4块类型和数据的校验值正是这种结构化的设计为信息隐藏创造了多种可能性篡改IHDR块中的宽度/高度值实际图像数据可能比声明的尺寸更大异常CRC校验值CRC值本身可能包含隐藏信息伪装的数据块类型非常规块类型或错误标记的块IDAT块中的异常数据压缩图像数据中的隐藏信息提示使用010 Editor等二进制编辑器查看PNG文件时可以安装PNG模板它能自动解析文件结构并高亮显示异常部分。2. IHDR块尺寸篡改与CRC校验攻击IHDR块是PNG文件中第一个数据块包含了图像的基本信息。其中宽度和高度字段是最常被篡改的目标。2.1 宽度/高度篡改在CTF题目中出题人经常故意设置错误的宽度或高度值使得图像显示不完整。要修复这种篡改我们需要确定正确的宽度和高度计算对应的CRC校验值修改文件并保持结构完整以下是一个Python脚本示例用于暴力破解正确的宽度和高度import zlib import struct def fix_png_dimensions(filename, crc_key): with open(filename, rb) as f: data f.read() ihdr_start 12 # IHDR块开始位置 ihdr_end 29 # IHDR块结束位置 ihdr_data bytearray(data[ihdr_start:ihdr_end]) for width in range(4096): for height in range(4096): # 修改宽度和高度字段 width_bytes struct.pack(i, width) height_bytes struct.pack(i, height) for i in range(4): ihdr_data[i4] width_bytes[i] # 宽度字段偏移4字节 ihdr_data[i8] height_bytes[i] # 高度字段偏移8字节 # 计算CRC并比较 if zlib.crc32(ihdr_data) crc_key: # 找到正确尺寸修改文件 new_data bytearray(data) for i in range(4): new_data[16i] width_bytes[i] # 文件中的宽度位置 new_data[20i] height_bytes[i] # 文件中的高度位置 with open(fixed_filename, wb) as f: f.write(new_data) return width, height return None, None2.2 CRC校验值中的隐藏信息CRC校验本用于检测数据完整性但在CTF题目中CRC值本身可能包含隐藏信息。例如可打印ASCII字符CRC值可能对应可打印字符特定模式的值如递增序列或特定数字组合检查CRC值是否包含隐藏信息的简单方法def check_crc_value(crc_value): # 将CRC值转换为字节 crc_bytes crc_value.to_bytes(4, byteorderbig) # 检查每个字节是否可打印ASCII for b in crc_bytes: if 32 b 126: print(chr(b), end) print()3. 异常数据块类型伪装与非常规块PNG规范定义了多种标准数据块类型但允许存在辅助块ancillary chunks。这种灵活性为信息隐藏提供了空间。3.1 块类型伪装常见的手法包括修改IDAT块的类型标识如将IDAT改为其他值添加非标准块包含隐藏信息的自定义块块顺序异常如IDAT块不连续检测方法使用二进制编辑器查看块类型标识检查IDAT块是否连续且完整查找非标准块类型3.2 隐藏块示例分析在BUUCTF Findme题目中1.png的chunk[2]和chunk[3]缺少IDAT标识。修复步骤使用010 Editor打开文件定位到可疑数据块将块类型字段修改为IDAT十六进制49 44 41 54重新计算CRC校验值可选4. 文件尾与格式混淆技巧文件尾是另一个常见的信息隐藏位置但高手会采用更隐蔽的方式。4.1 文件尾附加数据虽然简单附加数据容易被发现但出题人常使用以下技巧格式混淆如将7z数据伪装成zip部分覆盖只修改关键字节而非整个文件头多重压缩嵌套多个压缩格式在Findme的2.png中文件尾有7z数据伪装成zip查找文件尾的异常数据识别7z签名37 7A BC AF 27 1C将7z签名改为zip签名50 4B 03 04提取隐藏文件4.2 自动化检测脚本以下Python代码可以检测文件尾的常见压缩格式def detect_trailing_data(filename): signatures { zip: bPK\x03\x04, 7z: b7z\xBC\xAF\x27\x1C, rar: bRar!\x1A\x07\x00, gzip: b\x1F\x8B\x08 } with open(filename, rb) as f: data f.read() for offset in range(-1024, 0): chunk data[offset:] for fmt, sig in signatures.items(): if chunk.startswith(sig): print(fFound {fmt} signature at offset {len(data)offset}) return offset return None5. EXIF元数据与非常规字段EXIF数据通常用于存储照片的拍摄信息但也可以隐藏关键数据。5.1 EXIF隐藏技巧非常规标签使用制造商特定的标签注释字段如UserComment、XPKeywords多语言数据在不同语言描述字段中隐藏信息查看EXIF数据的工具exiftool命令行在线EXIF查看器Python的PIL库5.2 Python提取EXIF示例from PIL import Image from PIL.ExifTags import TAGS def get_exif_data(filename): image Image.open(filename) exif_data image._getexif() if not exif_data: return None decoded {} for tag_id, value in exif_data.items(): tag_name TAGS.get(tag_id, tag_id) decoded[tag_name] value # 检查可疑字段 suspicious_fields [UserComment, XPKeywords, MakerNote] for field in suspicious_fields: if field in decoded: print(f{field}: {decoded[field]}) return decoded6. 综合检测流程与工具链建立系统化的PNG隐写检测流程至关重要。以下是推荐的步骤初步检查文件命令检查file image.png十六进制查看xxd image.png | less字符串提取strings image.png结构分析使用pngcheck验证文件结构010 Editor配合PNG模板分析内容提取binwalk检测嵌入文件foremost分离文件steghide检测隐写如有密码尝试空密码视觉分析Stegsolve检查各颜色通道调整亮度/对比度发现隐藏信息元数据分析exiftool检查EXIF数据自定义脚本检查CRC值等推荐工具组合工具类型推荐工具主要功能二进制分析010 Editor, HxD可视化编辑与分析结构验证pngcheckPNG文件完整性检查隐写分析Stegsolve, zsteg视觉和算法检测元数据exiftoolEXIF信息提取脚本环境Python PIL自定义分析7. 防御性设计与实战建议了解攻击技术的同时也需要知道如何设计更隐蔽的隐写方案仅用于CTF比赛和合法场景。7.1 高级隐写技巧多层级隐藏结合多种技术如修改尺寸CRC值EXIF动态生成根据原始图像内容动态选择隐藏位置格式混淆制作半有效的PNG文件在不同解析器中表现不同7.2 实战建议建立检查清单系统化检查各个可能的信息隐藏点开发自定义工具针对常见比赛平台编写专用检测脚本记录异常模式积累不同出题人的偏好和习惯团队协作多人独立分析后比对结果在最近的一次CTF比赛中我遇到一个巧妙设计的PNG隐写题。表面看起来完全正常但实际隐藏信息的方式是在多个IDAT块中分散存储了经过特殊编码的数据。通过分析块的大小分布和压缩率差异最终定位到了异常点。这种经验告诉我系统化的分析流程比依赖单一工具更可靠。

更多文章