BugkuCTF –WEB-备份是个好习惯(备份源码泄露+md5漏洞)

先打开题目看一下

题目刚开始给了一串md5值

尝试先去解密一下

空密码??题目名字叫做备份是个好习惯。扫一下网站目录,瞅瞅有没有备份的文件啥的

发现了一个.bak文件,估计是index.php备份的源码,下载下来看一下

附上有关备份文件的知识:备份文件一般在后缀名后添加.bak或者.swp

<?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'], '?');//将url中?(包含?)后边的字符串赋值给变量str
$str = substr($str,1);//从第一个字符开始,后边的字符串赋值给变量str
$str = str_replace('key','',$str);//使用空字符串替换$str中的key
parse_str($str);
echo md5($key1);

echo md5($key2);
if(md5($key1) == md5($key2) && $key1 !== $key2){
    echo $flag."取得flag";
}
?>

1.strstr() 返回关键字之后的字符串一直到末尾。

strstr(string,search,before_search)  string(必须)被搜索的字符串,search(必须)关键字,beore_search(可选)默认为"false"的布尔值,如果设置为"ture",它将返回search参数第一次出现之前的字符串部分
<?php
echo strstr("I love Shanghai!","I");
?>


I love Shanghai!

2.substr(string,start,length),返回string中从第start个字符开始之后的字符串。(length选填)如果有length则为start之后length长度的字符串
3.str_replace() 函数以其他字符替换字符串中的一些字符(区分大小写)。
str_replace(find,replace,string,count) 在(string)中查找(find),并使用(replace)进行替代      count 替换次数(默认1次)

4.parse_str() 函数把查询字符串解析到变量中    parse_str(string,array)     如果未设置 array 参数,则由该函数设置的变量将覆盖已存在的同名变量

get到index.php的源码了,接下来就是对代码进行审计

原来输出这么一长串md5是两个key的md5接起来的。。

接下来就是想办法满足if(md5($key1) == md5($key2) && $key1 !== $key2)这个条件了,就可以获得flag了

这个条件的意思是,如果两个值加密后的md5值一样,且他们未加密的值不一样则输出flag


方法一

md5()函数无法处理数组,如果传入的为数组,会返回NULL,所以两个数组经过加密后得到的都是NULL,也就是相等的。

$str = str_replace('key','',$str);这句把key置为空;看到md5()函数,可分别赋值240610708和QNKCDZO。尝试后没变化,想到key被置空了,可以用kkeyey替换key。所以构造?kkeyey1=240610708&kkeyey2=QNKCDZO 得到flag

240610708 和 QNKCDZO md5值类型相似,但并不相同,在“==”相等操作符的运算下,结果返回了true。这是个经典的漏洞,只需要找到md5值为0exxx(xxx全为数字,共30位),这里我提供4个都可以通过的值:240610708、QNKCDZO、aabg7XSs、aabC9RqS

<?php
echo md5(aabC9RqS);
//0e462097431906509019562988736854
echo md5(QNKCDZO);
//0e830400451993494058024219903391
echo md5(aabg7XSs);
//0e087386482136013740957780965295
echo md5(aabC9RqS);
//0e041022518165728065344349536299
?>

扩展小知识:

先注册密码为240610708的用户A。
然后用密码QNKCDZO尝试登录用户A。
倘若成功登录,则证明此网站采用了不完备的加密体制md5一次加密。

先注册密码为0E33455555的用户A。
然后用密码0E234230570345尝试登录用户A。
倘若成功登录,则证明此网站采用了明文进行存储密码!

方法二

string md5 ( string $str [, bool $raw_output = false ] )

md5()中需要传入的是一个string类型的参数,当我们传递一个array时,它是不会报错的,函数无法求出array的MD5值,这样导致任意两个array的MD5值都相等,从而绕过输入数值的判断,在ctf代码审计中经常遇见。

md5无法处理数组,如果md5()传入了数组,则会显示为空,所以构造?kkeyey1=240610708&kkeyey2=QNKCDZO

flag就直接爆出来了

参考:

https://www.jianshu.com/p/d433d9f89102

http://www.w3school.com.cn/php/index.asp

猜你喜欢

转载自blog.csdn.net/qq_34449006/article/details/84262852
今日推荐