PNG CRC爆破

预备知识

PNG文件格式

  8字节 → PNG文件头

  再往后就是第一个数据块:数据块由4字节的数据域长度,4字节的类型码,指定长度(前面提到的数据域长度,这里IHDR就是0x0D个字节也即13字节)的数据,和4字节的CRC码组成。

  而IHDR的组成为:4字节宽度,4字节高度,1字节位深度,1字节颜色类型,1字节压缩方法,1字节滤波方法,1字节隔行扫描方法。

对什么数据做CRC

 crc就是对类型码数据域进行计算得到的

实际操作

以‘Buuoj 大白’为例

1. 题目提示“是不是屏幕太小了”,打开dabai.png时报错:“解码错误,不支持或无效的文件”所以应该是图片宽高的错误导致校验不通过。该图片宽679,高256,应该要调整高度。

2. 所以我们应当以二进制形式读入该png文件,然后采集下图红框所圈的部分数据,计算其CRC,将结果与后4字节的校验码进行比对。因为调整高度,所以只需对蓝框中的数据进行修改。

3. 代码如下。

复制代码
 1 import struct
 2 import binascii
 3 from Crypto.Util.number import bytes_to_long
 4 
 5 img = open("dabai.png", "rb").read()
 6 
 7 for i in range(0xFFFF):
 8     stream = img[12:20] + struct.pack('>i', i) + img[24:29]
 9     crc = binascii.crc32(stream)
10     if crc == bytes_to_long(img[29:33]):
11         print(hex(i))
复制代码

  高度上限应该不是很大, 这里只遍历 0~0xFFFF。此外,因为img[12:20]等输出的结果是bytes, 所以这里需要利用struct对整型数据格式化, 将其打包为字节流。另外格式符i意味着,4字节的整型。

  而且默认是小端输出,需要改成大端输出。大小端输出方式对比如下(以0x100为例):

  以上代码的输出结果为`0x1df`,所以利用winhex将图片高度部分对应的数据改为0001DF即可正常打开该PNG文件。

Reference

1. https://blog.csdn.net/hherima/article/details/45847043?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-5.edu_weight&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-5.edu_weight

2. https://dev.gameres.com/Program/Visual/Other/PNGFormat.htm

3. https://blog.csdn.net/qq_30638831/article/details/80421019

posted @   vict0r  阅读(2747)  评论(0编辑  收藏  举报
编辑推荐:
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
阅读排行:
· 为DeepSeek添加本地知识库
· 精选4款基于.NET开源、功能强大的通讯调试工具
· DeepSeek智能编程
· 大模型工具KTransformer的安装
· [计算机/硬件/GPU] 显卡
点击右上角即可分享
微信分享提示