前言
还是觉得自己练习得不够,太菜了。希望透过这道题再了解一点绕过的知识。话不多说,整活!!
解题
我们先打开这个靶场,
好家伙,这怎么看,先看看源码吧。哎哟,不错哦,源码里能清清楚楚的看到。我把代码扔下面。
<?php 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'); } }Please input first ?>
别看这么长,其实是很简单的。审计一下代码。
第一层
有一个很简单的绕过
(md5($id) === md5($gg) && $id !== $gg)=true
传入数组,使得md5($id)===md5($dd)===null
,然后设置两个不同的键值即可。
我们可以利用md5数组绕过。因为md5()函数无法处理数组,如果传入的为数组,会返回NULL,所以两个数组经过加密后得到的都是NULL,也就是相等的。
这样我们可以构造pyload:
?id[]=1&?gg[]=2
第一步成功了。
第二层
s_numeric()函数用1234567a绕。1234567a是字符串,但是弱比较的时候,1在前,php会将其整体转成数字,就可以通过比较了。
成功拿到flag