PHP md5() 大坑

看到有一个很有意思的测试,代码大概是下面的感觉:

如何得到 $flag 的值???

 


 

 

这个东西是我在搜 MD5 碰撞的时候搜出来的,但实际上这个东西和 MD5 碰撞毛子关系都没有,这个纯粹是PHP的毛病。

做个测试就好。上面代码的DEMO放在这里

看起来似乎除了 MD5 碰撞没有其它办法,但是,如果我们提交?pass=QNKCDZO,我们就会惊奇的发现居然通过验证了!!!(可以去自己试试,DEMO在上面

很显然,

md5( ‘QNKCDZO’ ) = 0e830400451993494058024219903391

md5( ‘240610708’ ) = 0e462097431906509019562988736854

这两除了开头是 0e 后面基本上都不一样,PHP怎么会判断它们相等???

找到官方文档,一切水落石出

http://php.net/manual/zh/language.operators.comparison.php

因为PHP是弱语言,会自动把 xe 开头的字符串当科学计数法转成数字再进行比较,那自然 0e 后面不管跟什么东西转成数字都是0,自然判断是会相等。

修复方法: 换用 === (强制判断类型相等

这些结果都是 (bool)true

[code lang=”php”]
var_dump(md5(‘240610708’) == md5(‘QNKCDZO’));
var_dump(md5(‘aabg7XSs’) == md5(‘aabC9RqS’));
var_dump(sha1(‘aaroZmOk’) == sha1(‘aaK1STfY’));
var_dump(sha1(‘aaO8zKZF’) == sha1(‘aa3OFF9m’));
var_dump(‘0010e2’ == ‘1e3’);
var_dump(‘0x1234Ab’ == ‘1193131’);
var_dump(‘0xABCdef’ == ‘ 0xABCdef’);
[/code]

这些都由 0e 开头
s878926199a
s155964671a
s214587387a
s214587387a
sha1(‘aaroZmOk’)
sha1(‘aaK1STfY’)
sha1(‘aaO8zKZF’)
sha1(‘aa3OFF9m’)

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注