CTF 杂项图片隐写:3 类文件头修复实战(PNG/JPG/GIF 结构解析)
CTF 杂项图片隐写3 类文件头修复实战PNG/JPG/GIF 结构解析在CTF竞赛的杂项Misc题目中图片隐写类题目往往考验选手对文件格式的底层理解能力。不同于常规的隐写工具使用当遇到文件头损坏、尺寸被修改等特殊题型时仅靠工具扫描可能无法解决问题。本文将深入解析PNG、JPG、GIF三种常见图片格式的文件结构并提供可复用的修复方法与自动化脚本。1. 图片文件结构核心原理理解文件结构是修复损坏文件的基础。不同图片格式通过特定的文件头签名和数据块结构来存储图像信息格式文件头签名HEX结束标记HEX关键数据块PNG89 50 4E 47 0D 0A 1A 0A无固定结束符IHDR, IDAT, IENDJPGFF D8FF D9SOI, EOI, APPnGIF47 49 46 38 39(37) 613BHeader, GCT, Image常见损坏场景文件头被部分或全部覆盖关键数据块被篡改如IHDR中的尺寸字段文件尾被追加多余数据多文件拼接造成的结构混乱2. PNG文件修复实战PNG文件采用分块存储结构每个数据块包含长度、类型、数据和CRC校验四部分。修复时需要重点关注以下三个核心数据块2.1 IHDR块修复IHDR块存储图片的宽度和高度信息各占4字节大端序。当图片显示不全时可能需要修改这两个字段。通过Python可快速定位并修改import struct def fix_png_dimensions(file_path): with open(file_path, rb) as f: data f.read() # 定位IHDR块文件头后84416字节开始 width struct.unpack(I, data[16:20])[0] height struct.unpack(I, data[20:24])[0] print(f原始尺寸: {width}x{height}) # 修改高度为原始值2倍示例 new_height height * 2 f.seek(20) f.write(struct.pack(I, new_height))2.2 CRC校验修复修改IHDR后必须重新计算CRC校验值。使用zlib库可自动修复import zlib def fix_png_crc(file_path): with open(file_path, rb) as f: data f.read() ihdr_start 12 # IHDR块起始偏移 ihdr_end 29 # IHDR块结束偏移 ihdr_data data[ihdr_start:ihdr_end] # 计算新CRC并写入 new_crc zlib.crc32(ihdr_data) 0xffffffff f.seek(29) f.write(struct.pack(I, new_crc))注意CRC校验错误会导致图片无法正常显示但部分查看器可能忽略该错误3. JPG文件修复技巧JPG文件采用分段标记结构每个段以FF开头后跟类型标识。修复时需要特别注意3.1 文件头尾修复标准文件头FF D8SOI标准文件尾FF D9EOI使用dd命令可快速提取有效JPG数据# 从损坏文件中提取完整JPG dd ifcorrupt.jpg bs1 skip$(grep -obaP \xFF\xD8 corrupt.jpg | cut -d: -f1) offixed.jpg3.2 分段结构解析典型JPG分段结构示例FF D8 SOI FF E0 APP0 (JFIF信息) FF DB DQT (量化表) FF C0 SOF0 (帧开始) FF C4 DHT (霍夫曼表) FF DA SOS (扫描开始) ...图像数据... FF D9 EOI当遇到文件截断时可尝试以下修复步骤使用hexdump -C file.jpg | grep -A 10 -B 10 ff d8定位有效起始位置检查是否存在完整的FF D9结束标记使用jpeginfo -c file.jpg验证文件完整性4. GIF文件修复方法GIF文件包含全局颜色表和多帧图像数据。关键修复场景包括4.1 文件头修复标准GIF89a文件头结构47 49 46 38 39 61 - GIF89a [2字节] 宽度 [2字节] 高度 [1字节] 包装字段 [1字节] 背景色索引 [1字节] 像素宽高比4.2 多帧数据提取当GIF包含隐藏帧时可使用Python提取from PIL import Image def extract_gif_frames(gif_path): with Image.open(gif_path) as img: for i in range(img.n_frames): img.seek(i) img.save(fframe_{i}.png)5. 自动化修复工具开发结合上述原理我们可以开发一个多功能修复脚本import argparse import binascii def auto_fix_image(input_file, output_file): with open(input_file, rb) as f: header f.read(8) if header.startswith(b\x89PNG): print(检测到PNG文件尝试修复...) fix_png(input_file, output_file) elif header.startswith(b\xFF\xD8): print(检测到JPG文件尝试修复...) fix_jpg(input_file, output_file) elif header.startswith(bGIF): print(检测到GIF文件尝试修复...) fix_gif(input_file, output_file) def fix_png(input_file, output_file): # 实现PNG修复逻辑 pass def fix_jpg(input_file, output_file): # 实现JPG修复逻辑 pass def fix_gif(input_file, output_file): # 实现GIF修复逻辑 pass if __name__ __main__: parser argparse.ArgumentParser() parser.add_argument(-i, --input, requiredTrue) parser.add_argument(-o, --output, requiredTrue) args parser.parse_args() auto_fix_image(args.input, args.output)6. 典型CTF案例解析案例1被修改的PNG高度题目特征图片显示不全底部有截断解题步骤使用xxd image.png | head -n 5查看IHDR块定位到高度字段偏移20-23字节修改高度值为更大数值如00 00 01 00使用pngcheck验证修复结果案例2附加数据的JPG文件题目特征file命令显示JPEG image data, JFIF standard 1.01, ... extra bytes解题步骤使用binwalk image.jpg检测附加数据用dd ifimage.jpg bs1 skip1234 offlag.zip提取隐藏文件注意跳过完整的JPEG数据直到FF D9案例3损坏的GIF文件头题目特征图片查看器报Invalid GIF header解题步骤使用HxD查看前6字节应为47 49 46 38 39 61修复错误字节后检查逻辑屏幕描述符确保全局颜色表标志位正确在实际CTF比赛中建议选手掌握以下三板斧结构验证使用file、pngcheck等工具检查文件完整性十六进制分析通过xxd或HxD手动检查关键字段脚本化修复编写Python脚本批量处理同类问题