PNG文件头

(固定)八个字节89 50 4E 47 0D 0A 1A 0A为png的文件头

(固定)四个字节00 00 00 0D(即为十进制的13)代表数据块的长度为13

(固定)四个字节49 48 44 52(即为ASCII码的IHDR)是文件头数据块的标示(IDCH)

(可变)13位数据块(IHDR)

1)前四个字节代表该图片的宽
2)后四个字节代表该图片的高
3)后五个字节依次为:
Bit depth、ColorType、Compression method、Filter method、Interlace method

(可变)剩余四字节为该png的CRC检验码,由从IDCH到IHDR的十七位字节进行crc计算得到。

————————————————

原文链接:https://blog.csdn.net/weixin_45669205/article/details/108614950

原题

normal_png

难度系数: 2星

题目来源: 暂无

题目描述:暂无

题目场景: 暂无

题目附件: https://yeyusmile.top/upload/imgs/pngcrc32/normal_png.zip

爆破长和宽

根据crc爆破长度

# png crc爆破长宽
import zlib
import struct

# with open(r'./normal_png.png', 'rb') as image_data:
with open(r'./2.png', 'rb') as image_data:
    bin_data = image_data.read()
data = bytearray(bin_data[12:29])  # 读出Chunk Type Code域和Chunk Data部分
print(hex(zlib.crc32(data)))
print(zlib.crc32(data))
print("===================================")
# 计算原始CRC32值
crc32Hexstr = "0x"
for i in range(4):
    rep = str(hex(bin_data[i + 29])).replace("0x", "")
    if len(rep) == 1:
        rep = "0" + rep
    crc32Hexstr += rep
# crc32Hexstr="0x401f4a01"
crc32key = eval(crc32Hexstr)  # 转十进制
print("CRC32:%s(Hex) %s(Dec)" % (crc32Hexstr, crc32key))
print("============running==================")
n = 4096  # 4k分辨率
# 爆破高和宽
for w in range(n):
    width = bytearray(struct.pack('>i', w))  # q为8字节,i为4字节,h为2字节
    for h in range(n):
        height = bytearray(struct.pack('>i', h))
        for x in range(4):
            data[x + 4] = width[x]
            data[x + 8] = height[x]
        crc32result = zlib.crc32(data)
        if crc32result == crc32key:
            print("width:0x%s  height:0x%s" % (bytearray(width).hex(),
                                               bytearray(height).hex()))
            exit()

输出结果:
J:\PycharmProjects\pythonProject\venv\Scripts\python.exe J:/PycharmProjects/pythonProject/pngCRC.py
CRC32:0x36b4f5fd(Hex) 917829117(Dec)
============running==================
width:0x0000026c  height:0x0000040b

Process finished with exit code 0

把图片放到winhex

将高度036b修改为040b,得到flag

Q.E.D.