1. 进入环境,下载附件
给的一张png尾缀的文件,尝试双击打开,提示文件已损坏。猜测可能是文件头有问题,因此丢入winhex中,如图:
发现png文件头不对,去搜搜文件格式,进行修改。
2. 问题分析
查阅相关png图片的数据标识,https://blog.csdn.net/zz_Caleb/article/details/89927673:
先详细解释一下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计算得到。
也就是说我们可以通过爆破来得到高度和宽度
修改相关的头后,如图:
使用kali打开提示CRC错误,如图:
写到这里,无从下手,参考网上的脚本,提示png图片crc宽度爆破,搜了一下,看了看相关博客:
https://h3110w0r1d.com/archives/128/
根据提示,使用脚本进行宽度遍历
import binascii
import struct
with open('./pic/148a3ba22b8541f48f354f3e27f0aa4c.png', 'rb') as file:
# 得到文件的16进制数据
data = file.read()
for i in range(1024):
# 找到数据的12到16位(IHDR)
# struct.pack('>i', i)中>表示大端模式,i表示integer数据类型,将i为4位宽度进行表示
# data[20 : 29]表示IHDR中的后9位
# c表示IDCH和IHDR数据,用于后续crc校验
c = data[12:16] + struct.pack('>i', i) + data[20 : 29]
# 如果校验结果是符合winhex中图片的第13到16位的crc值,则爆破成功宽度
crc = binascii.crc32(c) & 0xffffffff
if crc == 0x932f8a6b:
print(i)
跑出的图片宽度为709,对应16进制为0x2c5
,我们在winhex中修改对应的宽度值,如图:
得到最终的可打开图片:
最终答案为:wdflag{Png_C2c_u_kn0W}