PNG CRC爆破

Posted vict0r

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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

以上是关于PNG CRC爆破的主要内容,如果未能解决你的问题,请参考以下文章

MISC:压缩包取证(zip爆破明文攻击伪加密CRC32碰撞)

MISC:压缩包取证(zip爆破明文攻击伪加密CRC32碰撞)

BUUCTF-大白(图片宽高问题)

BUUCTF-大白(图片宽高问题)

PNG CRC 是如何精确计算的?

BMZ-MISC-pic