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

【Misc】PNG宽高修改 - PNG图片宽高CRC爆破

引言

在CTF竞赛的MISC(杂项)题型中,PNG图片的宽高修改是高频考点之一。这类题目往往通过隐藏图片的真实尺寸,结合CRC校验或文件结构特性来干扰选手获取关键信息。本文将从文件结构解析宽高修改原理工具三个方面,深入探讨PNG图片的宽高修改技术,并附带具体操作示例。

一、PNG文件结构与宽高存储原理

PNG文件的固定头为 89 50 4E 47 0D 0A 1A 0A,用于标识文件类型。关键数据块IHDR位于文件头之后,存储图像的元数据。

图像元数据包括:

  • 宽度:IHDR块的第16-19字节(4字节,大端序存储)
  • 高度:IHDR块的第20-23字节(4字节,大端序存储)
  • 其他参数:色深、颜色等值。

在第二行(0010H)打头4字节就是宽度,紧随其后的就是高度。图示宽度为00 00 04 8A,高度为00 00 01 22。将16进制转换为10进制得到宽度为:1162,高度为290。
每个数据块末尾包含了4字节的CRC32校验码,用于验证数据块(包括IHDR类型码和宽高数据)的完整性。若直接修改宽高值而未更新CRC,图片将无法正常显示。但是某些图片浏览软件会忽视CRC32校验,直接显示修改后的值。

图中选中的蓝色底色字体(00 18 BF 68)则为此处IHDR的CRC32校验码。
校验码的计算方式参考:

import zllib
zllib.crc32(IHDR+widht+height+后部字符)

其实IHDR位一直从图中的49 48 44 52一直到00 18 BF的前面。

二、修改宽高

你可以直接使用010Editor修改宽度位置或高度位置。

上图是一个已经包含FLAG的图片,我们需要修改高度造成FLAG的不显示。

原图值是00 00 01 82,也就是386px,我们设置为200px,也就是00 00 00 C8

保存后,再次观察图片:

图片的下半部分已经被隐藏。

三、恢复宽高

当我们拿到这样一个Misc题目时,我们需要首先了解原图大概在多少。但是其实盲目修改,只要范围不是很大,也可以成功。
例如我直接改为00 00 01 C8

图片中同样也是会包含FLAG的,下部分黑色区域则是没有图像内容导致的。

我们使用Brute_Crack_PNG的GUI工具,可以轻松还原图片。

很明显当前PNG图片是高度位置不符,所以应该爆破高度,我们按照上图所示在工具中勾选爆破高度模式,点击开始爆破。

不出1秒,就找到了有效高度。
点击保存文件,即可保存修改后的图片。

修复的分毫不差。
工具地址:https://github.com/Moxin1044/Brute_Crack_PNG

为了效率,目前使用Go编写该项目,基本代码和原理可以参考master分支中的python版本,具体代码如下:

import zlibdef png_crc32_crack_wh(file_name):with open(file_name, 'rb') as f:hexdata = f.read().hex()PNG_data = hexdata[:16]if PNG_data == "89504e470d0a1a0a":IHDR = bytes.fromhex(hexdata[24:32])width = int(hexdata[36:40], 16)height = int(hexdata[44:48], 16)str2 = bytes.fromhex(hexdata[48:58])crc32 = int(hexdata[58:66], 16)add_num = 20000  # 最大宽高,合理修改快速出flagfor w in range(width, width + add_num):for h in range(height, height + add_num):width_bytes = w.to_bytes(4, 'big')height_bytes = h.to_bytes(4, 'big')if zlib.crc32(IHDR + width_bytes + height_bytes + str2) == crc32:return f"PNG图片宽度:{ hex(w)} | {w}\nPNG图片高度:{hex(h)} | {h}"if zlib.crc32(IHDR + width_bytes + height_bytes + str2) == crc32:breakelse:return "可能不是PNG文件,或文件头有修改。\nPNG文件头:89504e470d0a1a0a"if __name__ == "__main__":filename = "test.png"print(png_crc32_crack_wh(filename))
http://www.xdnf.cn/news/2578.html

相关文章:

  • 消息中间件
  • 传统行业的数字化转型:如何通过RTMP推流技术提升实时直播体验
  • Spring MVC 请求映射处理:@RequestMapping 与 @Pathvariable
  • H5实现一个二维码生成器页面
  • 华为OD机试真题——阿里巴巴找黄金宝箱Ⅰ(2025A卷:100分)Java/python/JavaScript/C/C++/GO最佳实现
  • MySQL 存储引擎与服务体系深度解析
  • 登高架设作业指的是什么?有什么安全操作规程?
  • 基于QT(C++)实现数字图像处理—Canny边缘检测
  • 【WEB3】web3.0是什么
  • FreeMarker语法深度解析与Node.js集成实践指南
  • 衡石科技:HENGSHI SENSE 数据权限解决方案
  • Shadertoy着色器移植到Three.js经验总结
  • 【Linux系统】详解Linux权限
  • AI工作流自动化与智能应用开发平台
  • WEB服务器的部署及优化
  • 线上JVM调优与全栈性能优化 - Java架构师面试实战
  • DataStreamAPI实践原理——快速上手
  • 学习笔记—双指针算法—移动零
  • [原创](现代Delphi 12指南):[macOS 64bit App开发]: NSString类型与CFStringRef类型字符串相互转换.
  • 通过数据增强打造抗噪音多模态大模型
  • MySQL 大数据量分页查询优化指南
  • Git 撤回合并提交
  • WPF之XAML基础
  • AlexNet网络搭建
  • OneNet云平台
  • java16
  • Java快速上手之实验五
  • 若依脱敏功能升级:接口返回想脱就脱,想不脱就不脱(实现灵活可控制的数据脱敏)
  • 手撕——贪吃蛇小游戏(下)
  • 【quantity】1 创建 crates.io 账号并上传 Rust 库