在CTF中,md5的题目太常见了,虽然有很多这方面的文章,但相对来说比较零散,这里主要将自己学习和比赛时遇到的md5弱类型和强碰撞的题目从浅到深地梳理一下。
本文涉及知识点实操练习:浅谈md5弱类型比较和强碰撞 相关实验:Weekly CTF(本课程旨在提供一些CTF题目给对CTF感兴趣的朋友们,让大家通过这些题目学习到相关知识。)
php中有两种比较的符号==与=====在进行比较的时候,如果比较一个数字和字符串或者比较涉及到数字内容的字符串,则字符串会被转换为数值并且比较按照数值来进行。
===在进行比较的时候,会先判断两种字符串的类型是否相等,再比较。
0e开头且都是数字的字符串,弱类型比较都等于0。
测试代码
由于md5不能加密数组,在加密数组的时候会返回NULL
所以,我们可以传入两个数组
可以传入两个md5加密后是0e开头的字符串,需要注意的地方是,这个以0e开头的字符串只能是纯数字,这样php在进行科学计算法的时候才会将它转化为0。可以查找以0e开头md5加密相等的字符串,也可以自己编写代码,提供以下脚本。
也可以传入两个数组,但不再适合传入两个0e开头的字符串,因为===是md5的强碰撞,进行了严格的过滤。
使用md5加密后两个完全相等的两个字符串来绕过过滤。
如何生成两个不一样的字符串,但是MD5是一样的呢。参考如何用不同的数值构建一样的MD5后,我们可以使用快速MD5碰撞生成器来构建两个MD5一样,但内容完全不一样的字符串。
fastcoll_v1.0.0.5.exe.zip
创建一个文本文件,写入任意的文件内容,命名为ywj.txt (源文件)
运行fastcoll输出以下参数。-p 是源文件,-o是输出文件
对生产的1.txt和2.txt文件进行测试
可以看到,1.txt和2.txt文件二进制md5加密后的结果完全相同。由于1.txt和2.txt文件中含有不可见字符,所以需要将其url编码后使用。可以看到url编码后的两个字符串不完全相同,满足我们输入两个不同参数的需要。
当题目限制不能传入数组,只能传入字符串时,如下例题,就只能采用解法2.
源码
首先查看一些strtr()函数的用法:
strtr() 函数转换字符串中特定的字符。
观察源码,要求传入四个参数,首先param1===param2,因为没有别的限制,所以我们可以传入两个数组。对于是str1和str2,首先str1只能是数字,且最后$a==$b,但md5_1 !=md5_2,所以我们不能传入两个md5加密后以0e开头的字符串。
又因为会将md5加密后的str1和str2中的cxhp替换成0123,也就是说c会被替换成0,所以一个ce开头的字符串会被替换成0e开头的字符串。
可以想到只要找到两个md5加密后是ce开头的字符串,或者一个md5加密后是ce开头的字符串,一个md5加密后是0e开头的字符串就可以绕过过滤。
构造脚本
这是一开始的脚本,返回值少,且执行速度慢。
这是进一步优化的脚本
观察代码,有一个rondom *** ,返回的是一个随机数,在这道题中,不需要清楚返回的是什么内容,我们只要知道返回的是一串数字就可以了。传入两个参数a和b,要求传入的是字符串,b会经过md5加密。最后要让$a.$r==$b。因为是弱类型比较,且只能传入字符串,想要的是两个0e开头的字符串进行比较,前面我们已经知道,以0e开头的字符串只能是纯数字,这样php在进行科学计算法的时候才会将它转化为0。所以保证$a以0e开头就可以了,因为$r是一串数字,所以$a.$r在php中还是可以被解析为0。因为$b是参数b经过md5加密而来,所以我们传入md5加密后是0e开头的字符串即可。
序言 在CTF中,md5的题型太普遍了,尽管有很多这些方面的文章内容,但相对而言较为零散,这儿关键将自身学习培训和赛事时碰到的md5弱种类和强撞击的题型从浅到深地整理一下。 文中涉及到知识要点实际...