当前位置: 首页 > news >正文

CTF实战:巧用文件结构修复图片宽高

1. CTF图片宽高修改实战入门

第一次参加CTF比赛时,遇到一张打不开的图片题目,我完全摸不着头脑。后来才知道,这类"图片隐写"题目往往通过修改图片文件结构中的关键参数来隐藏信息。最常见的套路就是篡改图片的宽高值,让图片无法正常显示,需要选手手动修复才能获取flag。

JPG和PNG作为最常用的图片格式,它们的文件结构就像乐高积木一样由多个标准化的"模块"组成。比如JPG文件以0xFFD8开头,PNG文件以固定的8字节签名开头。理解这些基础结构,就是解决图片宽高修改题目的第一步。

2. JPG文件结构与宽高修改

2.1 JPG文件格式深度解析

JPG文件就像一本精心编排的相册,每个章节都有特定的标记码引导。最重要的SOF0(Start of Frame)标记就是存放宽高信息的"黄金位置"。它的结构是这样的:

标记代码:0xFFC0(固定) 数据长度:2字节 精度:1字节(通常为08) 图像高度:2字节 图像宽度:2字节 颜色分量数:1字节 颜色分量信息:可变长度

实战中遇到过这样一个案例:用hex编辑器打开题目图片,搜索FFC0标记后,发现宽度被设为0000。这就是典型的宽高篡改手法——将实际尺寸清零导致图片无法渲染。

2.2 三步搞定JPG宽高修复

  1. 定位关键标记:使用010 Editor或WinHex搜索FFC0
  2. 读取原始数据:FFC0后第5-8字节就是高度和宽度(注意大端序)
  3. 修改数值:比如将异常的0000改为实际的0280(640像素)
with open('corrupted.jpg', 'rb') as f: data = f.read() sof0_pos = data.find(b'\xff\xc0') height = data[sof0_pos+5:sof0_pos+7] width = data[sof0_pos+7:sof0_pos+9] print(f"原始宽高:{int.from_bytes(width,'big')}x{int.from_bytes(height,'big')}")

记得修改后要检查SOF0段的CRC校验。有次比赛我就因为没校验,改完图片还是打不开,白白浪费半小时。

3. PNG文件结构与爆破技巧

3.1 PNG文件头与IHDR块

PNG的文件结构更像集装箱货轮,每个数据块(chunk)都有明确的标签。关键尺寸信息存放在IHDR块中,这个块的结构非常规范:

长度:4字节(固定13) 类型:4字节("IHDR") 宽度:4字节 高度:4字节 位深:1字节 颜色类型:1字节 压缩方法:1字节 滤波器:1字节 交错方法:1字节 CRC:4字节

遇到过最狡猾的题目是把IHDR块的CRC校验值也改了,导致常规编辑器直接报错。这时候就需要用到CRC爆破技术。

3.2 自动化爆破宽度实战

当遇到CRC校验正确的篡改时,可以写脚本爆破实际宽度:

import binascii import struct with open('flag.png', 'rb') as f: data = f.read() ihdr = data[12:29] # 获取IHDR块内容 for w in range(1000): # 假设宽度在1000像素内 # 重建IHDR块(替换宽度字段) new_ihdr = ihdr[:4] + struct.pack('>i', w) + ihdr[8:] # 计算CRC32(注意包含块类型和内容) crc = binascii.crc32(b'IHDR' + new_ihdr[4:13]) & 0xffffffff if crc == int.from_bytes(ihdr[13:17], 'big'): print(f"爆破成功!实际宽度:{w}") break

这个脚本我在三场不同比赛中都用到过,最快的一次只用了2秒就爆破出正确宽度。记得保存原始文件,有次我直接在内存中修改导致源文件损坏,不得不重新下载题目附件。

4. 高级技巧与避坑指南

4.1 双重校验陷阱

去年某CTF出了道阴险题目:不仅改了宽高,还同时在APP1段(Exif信息)里存了假尺寸。用常规方法修改后,某些图片查看器仍会读取Exif里的错误尺寸。解决方法是用exiftool彻底清除Exif数据:

exiftool -all= corrupted.jpg

4.2 尺寸与压缩的关联

修改JPG宽度时要注意,SOF0里的采样因子(在颜色分量信息中)会影响实际显示比例。有次我把800x600改为1600x300,结果图片显示异常扭曲,就是因为没同步调整采样因子。

4.3 工具链推荐

  • 010 Editor:二进制编辑神器,有现成的JPG/PNG模板
  • pngcheck:快速验证PNG文件结构
  • HxD:轻量级十六进制编辑器
  • Pillow库:Python处理图片的最后防线
from PIL import Image try: img = Image.open('modified.jpg') img.verify() # 验证图片完整性 except Exception as e: print(f"图片校验失败:{str(e)}")

5. 实战案例复盘

去年一道真题给出显示为100x100的图片,但flag明显被截断。用脚本读取真实尺寸发现实际是100x800,修改高度后果然显示完整二维码。关键点在于:

  1. 先用file命令确认是PNG24格式
  2. 发现IHDR显示的100x100与CRC校验匹配
  3. 怀疑存在IDAT块数据异常
  4. 最终发现题目在IDAT块后追加了隐藏数据

这种多层嵌套的题目,就需要结合hex编辑和Python脚本分析:

import zlib with open('challenge.png','rb') as f: data = f.read() idat_pos = data.find(b'IDAT') idat_data = data[idat_pos+4:idat_pos+8] # 解压缩IDAT数据 decompressed = zlib.decompress(data[idat_pos+8:-12]) print(len(decompressed)) # 通过数据量反推真实高度
http://www.jsqmd.com/news/1093510/

相关文章:

  • 月之暗面Kimi:一年估值飙升,激进技术与克制扩张并行,欲成“不被定义”大模型
  • wecomapi开发客户备注同步:如何处理员工备注与系统字段
  • 计算机Java毕设实战-基于 SpringBoot 的毕业文档提交审核管理系统高校毕业设计项目进程管控系统设计与实现【完整源码+LW+部署说明+演示视频,全bao一条龙等】
  • Ryujinx:在PC上免费体验Nintendo Switch游戏的全能模拟器
  • 元器件为什么会失效?
  • 一颗芯片撬动48款爆款产品:杰理2026最新矩阵与尚凌科技供应链布局揭秘
  • 开源 CI 模板上线:结合信号提取与 LLM 推理,检测 CI/CD 流水线滥用行为
  • 企业微信API开发会话数据进入业务系统时,需要注意哪些边界
  • 《电工学》核心解题思路精讲:从电路定理到暂态分析
  • 《我那从“人工智障”一路打怪升级成“神”的室友》
  • Java的java.lang.StackWalker检查操作
  • A股量化策略日报(2026年06月29日)
  • 陆面生态水文模拟与多源遥感数据同化的实践技术应用
  • 2026 实测干货|5 款免费商用 AI 电商绘图软件,一键生成主图 / 详情页 / 活动海报
  • 【毕业设计】基于 SpringBoot 的毕业设计流程跟踪管理系统 毕业生项目进度与文档归档管理系统设计与实现(源码+文档+远程调试,全bao定制等)
  • 门窗十大品牌盘点:门窗十大品牌实力解析(2026最新)
  • 工控备件行业为什么都在用参数化管理ERP
  • LoadRunner 11.0 在 Windows 11 上的完整部署与本地化实战
  • 深入解析TI ADS4449评估模块:高速ADC性能验证与硬件设计实战
  • Redis 集群 Slot 分配策略
  • CW32L012的智能语音灯控实现案例分享
  • 腾讯云大数据携手工商银行——存算分离架构落地实践,共绘数智金融新蓝图
  • 2026年最新|大模型备案资料规范指南
  • 从单线程到多线程 IO,Redis 7.2 到底快了多少?
  • LLM 幻觉问题全面解析
  • 2026年苍蓝前线最新礼包码有哪些?速来了解兑换秘诀!
  • DataBuff 发布 v0.1.1 稳定版:5 分钟跑起,AI 排障与 OpenTelemetry 能力亮点十足
  • 从0开始学梯形图:10个经典案例,一次讲透!
  • C/C++ 堆与栈的区别——面试完整知识体系
  • 怎么知道供应商在不在行业黑名单里