PNG图片宽高CRC爆破
CRC
这里的CRC指的是CRC32,也就是PNG图片的一个效验位,是一种不可逆运算,类似于MD5,作为数据效验或效验文件的完整性使用
图片宽高
CRC校验码
当一个png图片宽高有问题时,010回有CRC报错
原理
文件头89 50 4E 47 0D 0A 1A 0A
头部数据块长度为13 00 00 00 0D
IHDR数据块 49 48 44 52
宽 00 00 02 A7
,高 00 00 01 00
08 06 00 00 00
5个字节依次为Bit depth,ColorType,Compression method,Filter method,Interlace method
CRC
校验码6D 7C 71 35
原理就是 17个字节进行CRC计算得到
爆破CRC值
import zlib
import struct
import argparse
import itertoolsparser = argparse.ArgumentParser()
parser.add_argument("-f", type=str, default=None, required=True,help="输入同级目录下图片的名称")
args = parser.parse_args()bin_data = open(args.f, 'rb').read()
crc32key = zlib.crc32(bin_data[12:29])
original_crc32 = int(bin_data[29:33].hex(), 16)if crc32key == original_crc32:print('宽高没有问题!')
else:input_ = input("宽高被改了, 是否CRC爆破宽高? (Y/n):")if input_ not in ["Y", "y", ""]:exit()else:for i, j in itertools.product(range(4095),range(4095)):data = bin_data[12:16] + struct.pack('>i', i) + struct.pack('>i', j) + bin_data[24:29]crc32 = zlib.crc32(data)if (crc32 == original_crc32):print(f"\nCRC32: {hex(original_crc32)}")print(f"宽度: {i}, hex: {hex(i)}")print(f"高度: {j}, hex: {hex(j)}")exit(0)
import zlib
import structf = open("./dabai.png", "rb").read()crc = zlib.crc32(f[13:29])
orig_crc = int(f[29:33].hex(), 16)if crc == orig_crc:print("没问题")
else:for width in range(4095):for height in range(4095):data = f[12:16] + struct.pack('>i', width) + struct.pack('>i', height) + f[24:29]crc = zlib.crc32(data)if crc == orig_crc:print(f"宽为:{width},hex:{hex(width)}")print(f"高为:{height},hex:{hex(height)}")
将数据类型按照指定的格式转换为字节序列
这里的参数 i 应该是一个 Python 中的整数变量,经过转换后得到对应的 4 字节
循环冗余校验