简介
0、md5是一种摘要算法,任何数据都可以取md5数据。 一般情况下使用的md5值为32位。
1、因为两个数据32位MD5的摘要信息需要完全一样,概率很低,所以一般用于校验一个文件在传输的过程中出现损坏的情况。比如某些网站下载大的镜像文件(一般是操作系统)的时候提供md5值。用于下载之后的完整性校验。
2、由于md5碰撞概率低,所以也可以作为文件篡改验证。 因为相同文件类型, 相同发布信息等情况下,串改的文件和未串改文件的md5基本上没有可能发生碰撞。
但是由于使用某些语言的不规范,也许在使用过程中会使md5失效。
今天的这道题来自于buuctf的 easyMD5(一般看见easy的都不easy) (这里有个疑问,为啥大师傅们都不承认他们自己出的题目很难)。
这道题分为三部分。
第一部分:奇怪的md5加密
在返回的头部给出的Hint(送分点。)。
++*select from 'admin' where passoword = md5($pass,true)**++
0、猜测开发者的目的是:将传入的数据进行md5加密了之后和数据库数据进行对比。 如果有返回就可以。(送命点)。 CTF猜密码就扯,那么这里就必然存在绕过。一般情况下没有md5的时候我们是用1' or 1这样去绕过。
1、那么如何保证md5加密了之后还有1'or1这样的数据。这里涉及的知识点就是md5()第二个参数:
++默认不写为FALSE。32位16进制的字符串++ ++TRUE。16位原始二进制格式的字符串++
这里刚好传输的也是string。那么有没有可能二进制出现这样的数据呢?理论上是有的, 但是很难, 但是退而求其次。我们可以找到一个'or'6 开头的数据:
ffifdyop
的时候加密的结果如下:
hex: 276f722736c95d99e921722cf9ed621c raw: 'or'6\xc9]\x99\xe9!r,\xf9\xedb\x1c string: 'or'6这里后面的是乱码
这里的or后以数字开头, 那么就会被认为or条件成立。 就绕过了。
第二部分
查看源码给出了代码(送分点)
这里需要满足两个条件:
1、++传入变量a和b且相互不相等。++
2、++传入的a和b 两者的md5相等。++
这里是个老生常谈的问题:PHP弱类型。 知识点: 当一个字符串以0e开头则会认为是一个指数数字而非字符串,而0的E一定永远为0。 那么只要找到两个md5之后以0e开头的就可以了。 s1091221200a 0e940624217856561557816327384675 s1665632922a 0e731198061491163073197128363787
第三部分
第三部分就比较硬核了。 1、传入两个不 全等 的数据。 2、md5值 全等。
第一:个找到两个数据md5就是全等(++dm5 32位总是数据有限,而字符串的长度是无限,总是有两个相同的++) 第二:绕过
++方法1:++ 正常情况下我们可以绕过。绕过的方法也是与PHP的md5方法相关,md5默认传参为string 然如果报错则为空
那么两个非字符串让其报错就可以, post传参param1[]=1¶m2[]就可以了。 因为md5无法处理数组。
++方法2++ 传入两个真的md5一样的数据
总结
CTF大师傅总是不会说自己的题目很难。也很难让他们认错。 就比如最近的签到杯。我很气!