PNG图片是由多个块(Chunks)组成,每个块包含长度、类型、数据和CRC校验码四个部分。其中,IHDR(Image Header)是PNG文件的首个块,包含了图像的基本信息,如宽度、高度、颜色类型等。CRC校验码则是用于验证该块数据的完整性和正确性。
PNG图片文件头各个部分代表的意义如下所示:
0-7八个字节:89 50 4E 47 0D 0A 1A 0A是PNG的文件头(固定格式)
8-11四个字节:00 00 00 0D 表示头部数据块的长度:13(固定格式)
12-15四个字节:49 48 44 52 表示文件头数据块的标识(固定格式)
16-19四个字节:00 00 01 F4 表示图片的宽度(不固定)
20-23四个字节:00 00 01 3F 表示图片的高度(不固定)
24-28五个字节:08 02 00 00 00 表示Bit depth(图像深度)、ColorType(颜色类型)、Compression method(压缩方法)、Filter method(滤波器方法)、Interlace method(隔行扫描方法)这五个字节不固定
29-32四个字节:37 0C 8F 0B为图片CRC校验值,从第12个字节到第28个字节进行CRC计算得到
在打CTF的时候,常常会遇到一些被修改了宽度或者高度的PNG图片,遇到这种情况时如何去判断图片是不是被修改了呢?这里介绍两个方法。
方法一:把PNG图片放到十六进制编辑器010Editor里面,如果图片被修改了宽度或高度,010Editor会提示CRC校验码不正确,如下图所示。
方法二:把PNG图片放到kali里面
如果图片的CRC不正确,也就是宽度或者高度被修改了,在kali里面是无法预览的,如上图所示。当CRC正确时才会显示预览,如下图所示。
当遇到被修改了宽度或者高度的图片时,我们如何把图片还原到图片本身的高度或者宽度呢?有的师傅可能通过手动调整PNG图片的宽度或者高度,有的时候可以调试成功,但有的时候是比较困难的。比如下面这张图,这张图是被放大很多的,手动去调宽度和高度的效率是很低的。
如果想要快速得到正确的宽度和高度,这里就涉及到CRC校验码的计算了。前面讲了,CRC校验码是用于校验PNG图片的IHDR块数据的完整性和正确性的,所以要根据IHDR数据块的内容计算CRC校验码。绝大多数情况下,修改图片时是没有修改CRC校验码的,所以图片中CRC校验码是正确的,利用正确的CRC校验码通过爆破可以知道原本图片的宽度和高度。
前面介绍PNG文件头格式的时候讲了CRC校验码由PNG文件头的第12个字节到第28个字节这17个字节进行计算得到的。CRC算法有多种,如CRC-8、CRC-16、CRC-32等,PNG文件通常使用CRC-32算法。
这里直接借助Python代码实现CRC计算
import zlib
import struct
import itertools
filename = ""
binData = open(filename, 'rb').read()
# 利用IHDR数据块中的数据计算CRC
crc32Key = zlib.crc32(binData[12:29])
# 获取文件中的CRC值
originCrc32 = int(binData[29:33].hex(), 16)
if crc32Key == originCrc32:
print('宽高没有问题!')
else:
print("图片的宽度/高度被修改了")
# 图片的最大高度是0xFF FF FF FF,但考虑到实际,0x0F FF就差不多了,也就是4095宽度和高度
for i, j in itertools.product(range(4095), range(4095)):
data = binData[12:16] + struct.pack('>i', i) + struct.pack('>i', j) + binData[24:29]
crc32Calc = zlib.crc32(data)
if crc32Calc == originCrc32:
print(f"nCRC32: {hex(originCrc32)}")
print(f"宽度: {i}, hex: {hex(i)}")
print(f"高度: {j}, hex: {hex(j)}")
break
图片就是上面的那个PNG图片
将图片放到010Editor中,发现CRC校验码是错误的,图片的宽度和高度被修改了,修改后的宽度是0x0141,高度是0x014C
用脚本计算正确的宽度和高度
通过计算知道,图片的宽度没有被修改,高度被修改了,还原后的图像如下图所示。
为什么拿这道题去分析呢?因为在这道题中,你无法通过题目提供的图片去判断是图片的高度被修改了还是宽度被修改了。下面这种图片一看就知道是高度被修改了,把图片的高度尽可能调大就行了。
以上内容如有描述不当之处,欢迎留言指正!
原文始发于微信公众号(Cyb3rES3c):Misc之CRC校验码
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论