0x00 起因
几年前在网上见过一个md5碰撞生成工具(fastcoll)
,当时也没感觉有什么用处。不过不久前看见了一篇工具作者的paper,才大概明白工具的用处:
Hash collisions and exploitations
看见知乎上也有人拿gif搞了个生成显示自己md5值图片
的工具,稍微研究了下md5格式,实现了不同图案相同md5值:
其实类似的思路还可以实现相同md5值,打印不同数据的exe(这里就不展开了,大家可以自己思考下怎么做)下载这两个exe文件:
0x01 先研究下大佬的paper
在读了一遍Hash collisions and exploitations这篇文章后,大致了解了fastcoll
这个工具的用处
fastcoll
可以根据已知的数据头,在其后面分别附加两组128字节的数据(如果没对齐,还会加上其他数据),生成两个文件,并保证两个文件的MD5值相同。
并且根据MD5的特性:在两个MD5相同的文件后,如果附加上MD5相同的数据,生成的两个文件MD5依旧相同(虽然MD5会变,但是两个文件MD5相同)。就是文章中给出的这个公式:
根据这个结论,我们可以得到如下结论:
利用fastcoll
,可以对固定开头和固定结尾的数据,生成两组不同的数据(数据内容不可控)拼接上头和尾,分别生成两个文件,保证他们的MD5相同。
0x02 分析fastcoll生成的数据
如果是写一个exe的话,利用起来比较简单,按规则判断下内存区域的哪部分数据就好了(也就是上面举的例子)。但是因为数据内容不可控,所以gif利用起来有些困难。
不过在分析了fastcoll
生成的数据后,发现工具只会在几个区域内产生不同的数据(只是位置确定,数据内容依旧不可控),如图:
经过多次实验,发现最后一位数据,两组输出的值相差总是为0x60。可以利用这一点做些文章
0x03 分析下GIF格式
可以看一遍glib出的文章:What’s In A GIF
如果打不开上面的链接,可以看我备份的页面:What’s In A GIF backup
根据格式,我们可以利用Comment Extension
来包住fastcoll
生成的“乱码”,然后利用上最后一位字节数据。
如果我们将fastcoll
生成的数据第123位(最后一处的不同位置),数据值用x
和y
代替(x
<y
),那么大体处理方式如下:
总的来说,就是一个文件会把图片数据包在注释里当注释处理,而另一个文件会把它当正常图片数据处理
0x04 开工
具体代码见https://github.com/chenxuuu/different-gif-same-md5
代码里的
md5_h
和md5_s
需要根据你是实际的图片内容进行重新生成(懒得写自动生成处理逻辑了)
根据代码生成的图片数据,需要从前半部分分割开来,删掉后面的全部数据,重新生成碰撞块数据。如图所示圈住的地方就是要去掉的部分:
然后根据生成后的开头数据,生成对应的碰撞块:
可以看到,我们需要的最后一位不同数据差值正好为128
字节,我们可以最多显示一百多字节的不同图片数据
同时数据前面还填充了一堆0x00用于对齐,这些数据在写这堆代码的时候就考虑到了,不需要再理会,我们只需要把下面的碰撞代码拎出来就行:
最终就可以生成两张md5相同的图片了:
结束
是不是还可以做点其他更好玩的东西?
怎么生成两张显示不同MD5相同的图片