png块的基本知识
前八个字节表示这是一个png
文件,然后接着的四个字节表示数据块长度,最后四个字节表示数据块类型码,比如这里的IHDR
类型码
文件署名域
8字节的PNG文件署名域用来识别该文件是不是PNG文件。该域的值是:
|十进制数|十六进制数|
|:-:|:-:|
|137|89|
|80|50|
|78|4e|
|71|47|
|13|0d|
|10|0a|
|26|1a|
|10|0a|
数据块
数据块分为关键数据块(critical chunk)**和辅助数据块(ancillary chunks)。
每个数据块都由下表所示的4个域组成
|名称|字节数|说明|
|:–:|:–:|:–|
|Length(长度)|4字节|指定数据块中数据域的长度,其长度不超过(231−1)(231−1)字节|
|Chunk Type Code(数据块类型码)|4字节|数据块类型码由ASCII字母(A-Z和a-z)组成|
|Chunk Data(数据块内容)|可变长度|存储按照Chunk Type Code指定的数据|
|CRC(循环冗余检测)|4字节|存储用来检测是否有错误的循环冗余码|
其中CRC是对Chunk Type Code域和Chunk Data**域中的数据计算得到,是一种校验码。
IHDR
域的名称 | 字节数 | 说明 |
---|---|---|
Width | 4bytes | 宽度,以像素为单位 |
Bit depth | 4bytes | 高度,以像素为单位 |
ColorType | 1byte | 图像深度:索引彩色图像:1,2,4或8 ;灰度图像:1,2,4,8或16 ;真彩色图像:8或16 |
Compression method | 1byte | 压缩方法 |
Filter method | 1byte | 滤波器方法 |
Interlace method | 1byte | 隔行扫描方法:0:非隔行扫描;1: Adam7(由Adam M. Costello开发的7遍隔行扫描方法) |
(更多方法参考链接)[https://www.cnblogs.com/senior-engineer/p/9548347.html] |
题目
题目来自攻防世界misc区的2-1
[https://adworld.xctf.org.cn/task/answer?type=misc&number=1&grade=1&id=4954&page=3]
下载得到一个图片,无法打开,那就是文件格式出了问题了
用HxD打开看看
好几个地方都出错了,根据png块的知识修改png标识先
剩下一个宽度未知,这里我们就需要用到CRC32碰撞的知识,由于CRC32是根据Chunk Type Code和Chunk Data计算而来的,因此类似于md5碰撞,我们这里也可以用脚本
1 | import os |
分析:
- data是取Chunk Type Code和Chunk Data的十六进制数据
- & 0xfffff 用于将byte数据转成int或者其他整形数据时,只取低八位,其他位数都为0
- 最后比较crc32的值,如果成功则说明宽度符合原本的宽度
Reference
[https://www.cnblogs.com/senior-engineer/p/9548347.html]
[https://www.cnblogs.com/vict0r/p/13258286.html]