CRC爆破png图片宽度和高度原理以及python代码

CRC爆破png图片宽度和高度原理以及python代码



1.PNG图片的格式

在这里插入图片描述

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

(2). 4个字节 00 00 00 0D 十进制为13,代表头部数据块的长度为13

(3). 4个字节 49 48 44 52 ASCII码为IHDR,表明数据块为IHDR

(4). 13位数据块(IHDR)(红色线条部分)
前四个字节代表该图片的宽 00 00 01 FF(不固定,可变)
后四个字节代表该图片的高 00 00 01 FF(不固定,可变)
后五个字节依次为: Bit depth、ColorType、 Compression method、 Filter method、Interlace method(不固定,可变)

(5). 剩余四字节为该png的CRC检验码 59 F1 D4 BE,由从IDCH到THDR的十七位字节进行crc计算得到。(黄色线条的部分)


可以使用网站手动验证一下CRC:

在这里插入图片描述

在线CRC计算网站

根据49 48 44 52 00 00 01 FF 00 00 01 FF 08 06 00 00 00 成功计算出来了CRC的数值:59 F1 D4 BE,和图片中的CRC数值无误!


2.CRC

影响上图的CRC的有49 48 44 52 00 00 01 FF 00 00 01 FF 08 06 00 00 00


49 48 44 52 ASCII码为IHDR,表明数据块为IHDR
00 00 01 FF 图片的宽
00 00 01 FF 图片的高
08 06 00 00 00 五个字节依次为: Bit depth、ColorType、 Compression method、 Filter method、Interlace method

      一般不会考虑最后5个字节的变化,所以可以根据CRC来爆破图片的宽度和高度。因为除了图片宽度和图片高度,再加上忽略的最后5字节,其他的都是固定的,所以只有图片宽度和高度会影响CRC数值。


3.Python爆破图片宽度和高度

import zlib
import struct
import argparse
import itertools


parser = 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]) # 计算crc
original_crc32 = int(bin_data[29:33].hex(), 16) # 原始crc


if crc32key == original_crc32: # 计算crc对比原始crc
    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)): # 理论上0x FF FF FF FF,但考虑到屏幕实际/cpu,0x 0F FF就差不多了,也就是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): # 计算当图片大小为i:j时的CRC校验值,与图片中的CRC比较,当相同,则图片大小已经确定
                print(f"\nCRC32: {hex(original_crc32)}")
                print(f"宽度: {i}, hex: {hex(i)}")
                print(f"高度: {j}, hex: {hex(j)}")
                exit(0)

运行效果:

在这里插入图片描述



参考文章:

struct.pack: https://blog.youkuaiyun.com/u012842630/article/details/85726870

png宽高被改,crc无脑爆破: https://blog.youkuaiyun.com/qq_61554462/article/details/123599109

png图片CRC爆破原理的学习: https://www.cnblogs.com/yunqian2017/p/14449346.html

CTF-bugku-misc-[隐写3]-png高度隐写和pngCRC校验: https://blog.youkuaiyun.com/m0_43405474/article/details/123361993

PNG格式的数据结构: https://blog.youkuaiyun.com/weixin_44949552/article/details/105231309

### 关于CRC校验与JPG图片宽度高度的相关破解方法 对于JPEG文件而言,其结构不同于PNG,在处理CRC校验以及修改图像尺寸方面存在差异。JPEG并不像PNG那样广泛采用CRC来验证数据完整性;相反,JPEG更倾向于依赖于标记段(Marker Segment)来进行分隔定义不同部分的数据。 当涉及到调整JPEG图像大小并绕过可能存在的简单形式的完整性检查时,通常不需要直接针对CRC进行破解操作。然而,如果确实遇到了某种机制阻止了非法修改,则可以考虑以下几种方式: #### 修改JPEG头中的尺寸信息而不破坏文件结构 由于JPEG不使用CRC作为主要保护手段之一,因此可以直接编辑二进制流内的特定位置以更改图像分辨率而无需担心复杂的校验问题。具体来说,DHT (Define Huffman Table) SOS (Start Of Scan) 之间的区域包含了实际像素值之前的一些元数据,其中包括量化表其他参数设置。但是需要注意的是,真正影响显示效果的关键字段位于SOI之后不久即SOFn(Start of Frame n),这里存储着压缩模式下的图像维度等基本信息[^1]。 为了实现这一点,可以通过十六进制编辑器定位到相应的偏移量处手动输入新的数值。不过这种方法要求对JPEG内部格式有足够的了解,并且要小心避免误改其他重要位点以免造成整个文档不可读取的情况发生。 #### 使用专门工具辅助完成任务 考虑到手工编码容易出错而且效率低下,建议借助现成的应用程序或库函数简化流程。例如Python Imaging Library(PIL)/Pillow提供了便捷的方法获取及设定图形属性,即使官方API不允许直接操控底层字节序列,仍然能够间接达到目的——先加载原图再按需重设新规格最后保存回去即可[^2]。 ```python from PIL import Image img = Image.open('example.jpg') new_width, new_height = img.size[0]*2, img.size[1]*2 # 假定放大两倍为例 resized_img = img.resize((new_width, new_height)) resized_img.save('modified_example.jpg', quality=95) ``` 值得注意的是上述代码片段仅展示了如何改变视觉呈现而非触及到底层比特串层面的操作。若目标是要学习有关低级细节的知识,则应该深入研究相关标准文档或是参考开源项目源码加深理解。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值