Bugku-web-备份是个好习惯

##备份是个好习惯

[Bugku,备份是个好习惯,CTF]
打开网页题目链接,只有一长段意义不明的字符,仔细看发现是两段字符的重复。容易想到是md5加密值,在线md5解密发现是空字符串,线索中断。
Bugku-web-备份是个好习惯
然后使用御剑后台扫描软件,或者其他扫描软件对网址进行扫描,扫到一个php文件:
Bugku-web-备份是个好习惯
直接访问http://123.206.87.240:8002/web16/index.php不成功,由题目提示想到可以尝试访问备份文件http://123.206.87.240:8002/web16/index.php.bak,得php源码如下:

<?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";
}
?>

由php源码可以得知后台验证的逻辑(所以php文件的安全很重要)。在key1和key2的md5值相等时,页面便反馈flag,而这个flag没有在index.php文件中定义过,那么一定是在包含的flag.php中。
尝试直接访问flag.php,理所当然地失败了。
重新审视代码逻辑。str是当前的URI中‘?’后面的字符串,并且去掉了’key’这个单词。而key1和key2是通过parse_str函数从str中解析出的,这里可以用kkeyey绕过。接下来也不用md5碰撞,而是可以利用php中md5()函数在参数类型是数组时返回NULL的特性,构造两个数组参数。具体如下:
http://123.206.87.240:8002/web16/index.php?kkeyey1[]=1&kkeyey2[]=2
得到flag: Bugku{OH_YOU_FIND_MY_MOMY}
另一种方法是利用md5加密后的值,如果是0exxxxx的格式,会被认为是科学计数法表示的0*10^xxxx,即这样格式的值总相等。下列字符串的md5值都是0e开头:

QNKCDZO

240610708

s878926199a

s155964671a

s214587387a

s214587387a

关于md5加密得到0e开头值的字符串,参考:https://blog.csdn.net/zpy1998zpy/article/details/80582974