BUUCTF在线评测BUUCTF 是一个 CTF 竞赛和训练平台,为各位 CTF 选手提供真实赛题在线复现等服务。https://buuoj.cn/challenges#[MRCTF2020]Ez_bypass启动靶机
有提示F12,那查看一下源码。和页面显示的代码一样的,就是格式更规范而已
include 'flag.php';
$flag='MRCTF{xxxxxxxxxxxxxxxxxxxxxxxxx}';
if(isset($_GET['gg'])&&isset($_GET['id'])) {$id=$_GET['id'];$gg=$_GET['gg'];if (md5($id) === md5($gg) && $id !== $gg) {echo 'You got the first step';if(isset($_POST['passwd'])) {$passwd=$_POST['passwd'];if (!is_numeric($passwd)){if($passwd==1234567){echo 'Good Job!';highlight_file('flag.php');die('By Retr_0');}else { echo "can you think twice??"; }}else{ echo 'You can not get it !';}}else{ die('only one way to get the flag');}
}else { echo "You are not a real hacker!"; }
}else{ die('Please input first');}
} You are not a real hacker!
代码讲述了get方法传递两个参数 gg 和 id ,使得它们的MD5值 强相等(===),但它们本身值并不相同。
而且使用post方法传递了一个 passwd 参数,并且需要确保这个参数值不是纯数字,还得使得参数值与 1234567 弱相等(==)
那么我们首先构造url传参 :?gg[]=s878926199a&id[]=s155964671a
解释一下:为什么这里我们参数传递的是数组,而不是直接传递字符串?
由于代码要求两个参数值的MD5值要 强相等(===)
如果我们传递的是?gg=s878926199a&id=s155964671a
那么这两个值的MD5分别是
0e545993274517709034328855841020
0e342768416822451524974117254469
在进行比较时,这两个值是不相等的,就会返回 false
然鹅当传递的值是数组时,进行MD5运算,两个都会返回Null
null===null 返回 true
如果,代码中MD5值的比较使用的是 弱相等(==)
那么就可以直接传递字符串
原因是在弱比较时,php会将 0e 开头的字符串解释为科学计数法的 0。
并且如果 0e 后续全是数字的话,php会认为它们是相等的
再使用post方法传递 passwd=1234567\
1234567\
1234567a
1234567+
1234567-
1234567*
都可以(不要使用 . 会被看成是小数点)
这样写 是因为使用的是弱相等
当php看到一个字符串与一个数字进行弱比较时,它会将这个字符串看成一个数字,当读取到非数字的部分它就会停止,所以这些非数字字符得放在1234567的后面
获得flag{5ab68b16-b084-4f10-8530-06f5726d5f53}