一.知识点
1.BMP文件
BMP文件主要有四部分组成,位图头、位图信息、调色板、位图数据。
bmp文件头(bmp file header):提供文件的格式、大小等信息
位图信息头(bitmap information):提供图像数据的尺寸、位平面数、压缩方式、颜色索引等信息调色板(color palette):可选,如使用索引来表示图像,调色板就是索引与其对应的颜色的映射表位图数据(bitmap data):就是图像数据
#关于存储
在BMP文件中,如果一个数据需要用几个字节来表示的话,那么该数据的存放字节顺序为“低地址村存放低位数据,高地址存放高位数据”。如数据0x1756在内存中的存储顺序为:
这种存储方式称为小端方式(little endian) , 与之相反的是大端方式(big endian)。
2.crc碰撞脚本
Misc中的有一类题目是要求我们知道加密后的rar文件中的内容。但是rar文件密码我们不知道,直接爆破密码也不是很现实。
但是当文件的大小比较小,或者字符数量较少时,就可以根据crc校验码来爆破出rar内部文件的内容。
这种类型的rar,flag由flag_0~flag_5组成。rar文件是有密码的,无法直接打开这些文件。
可以看到最后一列是对应文件的CRC校验码。并且每个文件只有4字节,所以可以看作每个crc校验码都对应了唯一的文件。
因此考虑CRC碰撞。
CRC碰撞原理就是构造一个和源文件等长的字符串,然后再对其进行CRC校验,比较校验码是否相同即可。
脚本如下:
import binascii
import string
dic=string.printable #打印出字符表
crc1=0x7DE0AB32
crc2=0xB1441D53
crc3=0x49BD11F5
crc4=0xB42F1DFA
crc5=0x8163F43E
crc6=0x1FC8FEE5
for i in dic:
for j in dic:
for n in dic:
for m in dic:
s=i+j+n+m
if(crc1==(binascii.crc32(s) & 0xffffffff)):
text1=s
if (crc2 == (binascii.crc32(s) & 0xffffffff)):
text2=s
if (crc3 == (binascii.crc32(s) & 0xffffffff)):
text3=s
if (crc4 == (binascii.crc32(s) & 0xffffffff)):
text4=s
if (crc5 == (binascii.crc32(s) & 0xffffffff)):
text5=s
if (crc6 == (binascii.crc32(s) & 0xffffffff)):
text6=s
print text1+text2+text3+text4+text5+text6
二.实例
ctfshow
misc29
跟上一题一样 把所有高度改为FF00 有一帧画面是有flag 截得即可得出
misc30
题目提示:正确的宽度是950。
修改宽度即可
misc31
题目提示:高度是正确的,但正确的宽度是多少呢。
首先我们要看图片文件大小是多少(通过010查看结尾位置在0x76f47,然后加上1,初始位置是0) 转成十进制(487256) 之后减去文件头(56) 除以字节(RGB每个像素由3个字节表示) 除以高度(150) 即可得到正确的宽度(1082)
buuctf
另外一个世界
首先看图片,没什么可用的信息,注意到图片转为文档最后有一串二进制代码,将其在随波逐流里转化一下,分八个一转,十进制拼接,得出flag(每个尝试一下得出十进制)
zip
打开文件后,发现很多zip文件,联想到crc碰撞脚本尝试,出来了base64编码,解码后发现存在文件,根据文件末尾得知是rar文件,接着把文件头加上使文件完整,即可得出flag(flag并不在文件里面,而是在注释中。)
参考资料:
http://t.csdnimg.cn/VrG5k
http://t.csdnimg.cn/3WswZ