misc24
flag在图片上面。
提示flag在图片上面,可能是图片的上半部分没有显示出来。因此用010editor打开,计算一下原始高度。
1.运行模板,得到结果(如果下方没有跳出结果就alt+4)




2.计算真实高度
真实高度=总大小÷3÷900=675000÷3÷900≈250。(÷3是因为RGB有三种颜色)
能这样计算是因为bmp未经压缩。
3.修改高度

4.保存文件,再次打开得到flag。

ctfshow{dd7d8bc9e5e873eb7da3fa51d92ca4b7}
misc25
flag在图片下面。
和misc24一样,但是文件格式变成png了。由于png经过压缩,所以不能直接计算文件大小。右键属性找到图片的宽和高:

或者用exiftool查看:

和刚才的宽高一样,我们直接把高度修改的大一点即可。(从00 96变成00 FF,这个数值可以自己任意调整,直到图片中能看到flag,当然不要直接改成FF FF,这样可能加载失败)

保存后重新查看图片:

ctfshow{494f611cc5842dd597f460874ce38f57}
misc26
flag还是在图片下面,但到底有多下面?。
看来还是修改高度的题,先查看一下文件属性:

和之前一样是900×150,根据题目的意思,这次的高度要修改得更大。

尝试了一下,发现02 FF可以看到flag:

这下必须找到真实得高度了。这涉及到png格式的CRC校验。
PNG文件中IHDR数据块的CRC校验值是通过对从第12到第28字节(包括宽、高、图像类型等信息)的17字节数据计算得出的,当实际宽高被篡改但CRC未同步更新时,会导致校验失败;因此可以通过爆破宽高值重新计算CRC,直至匹配原始CRC值,从而反推出正确的宽高。
编写代码进行爆破:
import binascii
import struct
# 换成实际的路径
png = open("E:\CTF\misc26\misc26.png", "rb").read()
# 提取IHDR块的原始CRC32值
crc32png = int(png[29:33].hex(), 16)
print(crc32png) # 输出原始CRC值用于调试
# 暴力枚举宽高(0-3999),寻找使CRC匹配的值
for i in range(4000): # 枚举宽度
for j in range(4000): # 枚举高度
# 构造IHDR数据块:'IHDR' + 宽 + 高 + 其他参数
data = png[12:16] + struct.pack('>i', i) + struct.pack('>i', j) + png[24:29]
# 计算CRC32校验值
crc32 = binascii.crc32(data) & 0xffffffff
# 如果计算出的CRC与原始CRC相等,说明找到正确的宽高
if crc32 == crc32png:
print(i, j) # 输出正确宽高(十进制)
print('hex:', hex(i), hex(j)) # 输出十六进制,便于修改文件
exit(0) # 找到后退出
运行后得到真实高度:

ctfshow{94aef125e087a7ccf2e28e742efd704c}
misc27
flag在图片下面
右键属性查看宽高,高度还是150:

用010editor打开,搜索00 96(150的16进制):

修改为00 FF(具体数值可以自己尝试,不一定是这个):

保存后查看图片:

ctfshow{5cc4f19eb01705b99bf41492430a1a14}
misc28
flag在图片下面。
右键属性:

同样的,用010editor打开,搜索00 96,这时发现搜不到了。查了资料发现,原来gif格式是小端序,因此应该是96 00。
在计算机系统和文件格式中,字节序指的是多字节数据(如16位、32位整数)在内存或文件中存储的顺序。大端序格式高位字节在前,低位字节在后,如PNG、JPEG、网络协议等;小端序格式低位字节在前,高位字节在后,如BMP、GIF、WAV、AVI、EXE、FLV等。其中,TIFF 文件开头会标明字节序,4D4D表示大端,4949表示小端,但标准 TIFF 通常以大端为主。
本题的GIF格式为小端序,因此高度是96 00。

找到两个。第一个出现的是逻辑屏幕高度(定义整个GIF画布的大小),第二个出现的是图像块高度(定义当前帧图像的实际尺寸);在GIF文件中,如果这两个高度不一致,可能导致解析失败或显示异常,因此在修复时必须一起修改为正确的值以确保文件能被正常读取。因此需要一并修改:

最低0.47元/天 解锁文章
1万+

被折叠的 条评论
为什么被折叠?



