ctf-misc PNG(文件头IHEDR)图片隐写

本文介绍PNG文件格式的基础知识,重点讲解如何通过爆破CRC校验来正确解析PNG图像的宽度信息,并修复异常文件头,以确保图片正常显示并获取其中隐藏的Flag。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

爆破crc校验所需要了解到的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)
    - 前四个字节代表该图片的宽
    - 后四个字节代表该图片的高
    - 后五个字节依次为:
    Bit depth、ColorType、Compression method、Filter method、Interlace method
- (可变)剩余四字节为该png的CRC检验码,由从IDCH到IHDR的十七位字节进行crc计算得到。

例题:
WDCTF-FINALS-2017

观察文件可以发现,文件头及宽度异常

00000000  80 59 4e 47 0d 0a 1a 0a  00 00 00 0d 49 48 44 52  |.YNG........IHDR|
00000010  00 00 00 00 00 00 02 f8  08 06 00 00 00 93 2f 8a  |............../.|
00000020  6b 00 00 00 04 67 41 4d  41 00 00 9c 40 20 0d e4  |k....gAMA...@ ..|
00000030  cb 00 00 00 20 63 48 52  4d 00 00 87 0f 00 00 8c  |.... cHRM.......|
00000040  0f 00 00 fd 52 00 00 81  40 00 00 7d 79 00 00 e9  |....R...@..}y...|
...

这里需要注意的是,文件宽度不能任意修改,需要根据 IHDR 块的 CRC 值爆破得到宽度,否则图片显示错误不能得到 flag。

import os
import binascii
import struct


misc = open("misc4.png","rb").read()

for i in range(1024):
    data = misc[12:16] + struct.pack('>i',i)+ misc[20:29]
    crc32 = binascii.crc32(data) & 0xffffffff
    if crc32 == 0x932f8a6b://CRS校验
        print i

得到宽度值为 709 后,恢复图片得到 flag。


2、宽度问题

图片地址:

题目链接:http://pan.baidu.com/s/1qY8sxZI 密码:5xam

图片尺寸为500x420(宽x高)

00 00 00 0D 说明IHDR头块长为13

49 48 44 52 IHDR标识

00 00 01 F4 图像的宽,500像素

00 00 01 A4 图像的高,420像素

最后四位CB D6  DF  8 A为CRC校验

将图片的高改为500像素就拿到flag了








### CTF杂项分类中的PNG文件处理 #### PNG 文件结构解析 PNG 图像文件遵循严格的二进制格式,其头部由特定的8字节签名组成:`89 50 4E 47 0D 0A 1A 0A`[^1]。此序列用于识别有效的 PNG 文件并防止误读其他类型的文件作为 PNG。 #### 术的应用实例 在某些情况下,攻击者可能会利用图像文件来嵌入秘密数据而不改变视觉外观。例如,在一次比赛中发现了一个看似普通的 PNG 文件 `final.png` 中藏有另一幅图象,通过使用专门设计用来检测此类操作的工具——Binwalk得以揭示藏的内容[^2]。 #### 处理损坏或篡改后的 PNG 文件恢复技术 当遇到因修改尺寸参数而导致无法正常展示的情况时(如高度设置不当使图片仅部分可见),可以通过调整关键字段重新计算循环冗余校验码(CRC),从而修复受损区域。具体实现方式如下所示: ```python import os import binascii import struct with open("misc4.png", "rb") as f: misc = f.read() for i in range(1024): data = misc[12:16] + struct.pack('>I', i) + misc[20:29] crc32 = binascii.crc32(data) & 0xffffffff if crc32 == 0x932f8a6b: print(f'Found correct width: {i}') ``` 上述脚本尝试遍历可能的宽度值直到找到匹配给定 CRC 的那个选项,进而修正被破坏的数据流以便于正确解码原始图形信息[^3]。 #### 关键块验证的重要性 对于任何试图手动编辑 PNG 文件的人来说,保持各个重要区块特别是 IHDR (Image Header Chunk) 完整性和准确性至关重要;否则即使是最细微的变化也可能引起整个文档失效或难以预料的行为变化[^4]。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值