用御剑可以扫描到一个备份文件,以.bak结尾
下载打开后可以看到index.php的代码
进行代码审计后
在这里插入代码片<?php
/**
* Created by PhpStorm.
* User: Norse
* Date: 2017/8/6
* Time: 20:22
*/
//构造语句:http://114.67.246.176:11212/?kekeyy1=QNKCDZO&kekeyy2=240610708
include_once "flag.php";//包含文件flag.php
ini_set("display_errors", 0);//配置选项
$str = strstr($_SERVER['REQUEST_URI'], '?');
//$_SERVER['REQUEST_URI']获取url除去host部分如www.baidu.com/?a=index.php变成?a=index.php
//strstr查找字符串?如果有输出?和后面部分
$str = substr($str,1);
//从第一个位置截取字符串str
$str = str_replace('key','',$str);
//查找str中的key并把key置空,由于只执行一遍因此可以双写绕过
parse_str($str);
//将变量实例化如key1=1,key2=2中key1和key2的值给下面的变量
echo md5($key1);//输出key1的MD5
echo md5($key2);//输出key2的MD5
if(md5($key1) == md5($key2) && $key1 !== $key2){//这就需要找两个md5相同但值不同的字符串如:QNKCDZO和240610708
echo $flag."取得flag";
}
?>
可知,核心是如何绕过if里的md5函数相关的条件。
条件是让找两个md5值相同的不同字符串, MD5算是一种映射,MD5值相同称为碰撞。碰撞概率很小,但也不是找不到,例如:QNKCDZO和240610708
这样就找到了flag。
但也可以利用MD5函数的特性,来绕过MD5函数。
典型MD5绕过思路有两个:
1.传md5值是0e开头的字符串,比如QNKCDZO 和 s214587387a(网上能搜到好多payload)
因为php在利用”!=”或”==”来对哈希值进行比较,它把每一个以”0E”开头的哈希值都解释为0
2.传递数组
因为向md5函数传递数组会返回NULL