0x01.前言:
背景介绍
根据提供的源代码,分析找出认证码
实训目标
1.掌握php隐式转换
2.了解md5的加密解密
解题方向
审计源代码,需要找一个值,这个值的md5值在php中==题中给定值的md5值
0x02.分析过程:
启动靶场环境后,根据靶场提示下载源代码:
<?php error_reporting(0); $a1 = md5('QNKCDZO'); $a = @$_POST['pass']; $a2 = @md5($a); if(isset($a)){ if ($a != 'QNKCDZO' && $a1 == $a2) { /** 内容省略! **/ exit(); } else { echo '<script>alert(\'认证错误\');window.location.href=\'/index.html\';</script>'; }} ?>
经过分析,这里是要将a的md5值和a1的md5值相同,但a又不能为QNKCDZO。
这里利用的是PHP隐式转换,由于 PHP 是弱类型语言,在使用 == 号时,如果比较一个数字和字符串或者比较涉及到数字内容的字符串,则字符串会被转换为数值并且比较按照数值来进行。此规则也适用于 switch 语句。上述例子中的两个字符串恰好以 0e 的科学记数法开头,字符串被隐式转换为浮点数,实际上也就等效于 0×10^0 ,因此比较起来是相等的。
把“QNKCDZO”md5加密得到0e830400451993494058024219903391,发现是0e开头的字符串,然后百度找一下PHP处理0E的漏洞找到这个。
具体参考:https://segmentfault.com/a/1190000002784965
链接部分摘录:
这里可以利用PHP这一特性来探测网站密码加密方式的方法
<?php var_dump(md5('240610708') == md5('QNKCDZO')); var_dump(sha1('aaroZmOk') == sha1('aaK1STfY')); var_dump('0x1234Ab' == '1193131'); ?>
结果都是
bool(ture)
bool(ture)
bool(ture)
如果在一个网站,使用240610708作为密码,然后用QNKCDZO登陆,结果可以登录的话,说明密码是以MD5方式保存的。类似的,如果用aaroZmOk作为密码,然后用aaK1STfY登陆,结果可以登录的话,说明密码是以sha1方式保存的。第三种当然就是明文存储了。