earph0n3's doc Help

png高度爆破

IHDR的结构

png图片的各种基础信息保留在 IHDR 块中, IHDR 块的数据部分长度固定为 13 个字节, 整个数据的分布如下:

字段名称

字段长度(字节)

描述及取值范围

length

4

IHDR数据块的长度, 固定为13字节

type

4

IHDR的标志, 固定为字符串 "IHDR"

Width

4

图像的宽度,单位为像素

Height

4

图像的高度,单位为像素

Bit depth

1

图像的位深度,即每个颜色通道的比特数

Color type

1

图像的颜色类型

Compression method

1

图像的压缩方法

Filter method

1

图像的滤波器方法

Interlace method

1

图像的扫描方法

一个完整的 IHDR 块还会在末尾加上一个四字节的 crc, 在010中查看是这样的(整个chunk[0]):

image-20241022134540382.png

IHDR 之前的是文件头, 占8个字节

crc的计算

整个 IHDR 块最后的 crc 值 是直接通过 typeInterlace method 这一段数据计算得到的

可以通过调用 zlib 模块的 zlib.crc32(data) 来完成计算, 也就是说可以通过遍历整个数据段, 爆破高度值并计算crc来与最后的 crc进行对比

读取文件信息

使用 with open 打开文件, 并用 read 逐步读取对应的字节数并将其打印出来

# 获得png图片的路径 png_path = input("输入png图片的路径:") # 打开图片 with open(png_path, 'rb') as f: # 文件头 head = f.read(8) print(f"文件头: \t\t\t{head}") # length ihdr_length = f.read(4) print(f"length字段: \t\t\t{ihdr_length}") # type ihdr_type = f.read(4) print(f"type字段: \t\t\t{ihdr_type}") # width width = f.read(4) print(f"width字段: \t\t\t{width}") # height height = f.read(4) print(f"height字段: \t\t\t{height}") # bit_depth bit_depth = f.read(1) print(f"bit_depth字段: \t\t\t{bit_depth}") # color_type color_type = f.read(1) print(f"color_type字段: \t\t{color_type}") # compression_method compression_method = f.read(1) print(f"compression_method字段: \t{compression_method}") # filter_method filter_method = f.read(1) print(f"filter_method字段: \t\t{filter_method}") # interlace_method interlace_method = f.read(1) print(f"interlace_method字段: \t\t{interlace_method}") # crc crc = f.read(4) print(f"crc的值: {crc}")

遍历高度值

使用for循环遍历高度并组成新的ihdr块:

for new_height in range(1000): # 将整型打包为字节 new_height = struct.pack(">I", new_height) # 拼接成新的ihdr ihdr = (head + ihdr_length + ihdr_type + width + new_height + bit_depth + color_type + compression_method + filter_method + interlace_method) print(ihdr)

计算crc

# 使用zlib的crc32方法计算crc new_crc = zlib.crc32() # 返回的是整数 # 使用pack进行打包 new_crc = struct.pack(">I", new_crc) # 判断计算的crc是否等于原来的 if new_crc == crc: print(new_crc) break else: pass

整合

将前面的代码整合起来得到:

import struct import zlib # 获得png图片的路径 png_path = input("输入png图片的路径:") # 打开图片 with open(png_path, 'rb') as f: print("读取文件信息......") # 文件头 head = f.read(8) print(f"文件头: \t\t\t{head}") # length ihdr_length = f.read(4) print(f"length字段: \t\t\t{ihdr_length}") # type ihdr_type = f.read(4) print(f"type字段: \t\t\t{ihdr_type}") # width width = f.read(4) print(f"width字段: \t\t\t{width}") # height height = f.read(4) print(f"height字段: \t\t\t{height}") # bit_depth bit_depth = f.read(1) print(f"bit_depth字段: \t\t\t{bit_depth}") # color_type color_type = f.read(1) print(f"color_type字段: \t\t{color_type}") # compression_method compression_method = f.read(1) print(f"compression_method字段: \t{compression_method}") # filter_method filter_method = f.read(1) print(f"filter_method字段: \t\t{filter_method}") # interlace_method interlace_method = f.read(1) print(f"interlace_method字段: \t\t{interlace_method}") # crc crc = f.read(4) print(f"crc的值: {crc}\n") print("爆破高度.....") # 假定高度是0-999 for new_height in range(1000): # 将整型打包为字节 new_height = struct.pack(">I", new_height) # 拼接成新的ihdr ihdr = (ihdr_type + width + new_height + bit_depth + color_type + compression_method + filter_method + interlace_method) # 使用zlib的crc32方法计算crc new_crc = zlib.crc32(ihdr) new_crc = struct.pack(">I", new_crc) if new_crc == crc: print("计算得到的crc:", new_crc.hex()) print("原来的高度是:", height.hex()) break else: pass
03 十一月 2024