进入环境,发现php代码如下,这一题应该考察的是代码审计的能力,如何绕过各个判断。
首先第一个判断是:
if(isset($a) && intval($a) > 6000000 && strlen($a) <= 3)
intval函数的作用是返回是获取给定变量的整数值,对各个类型的输入的输出如下所示。第一个判断要求a的值大于6000000且长度要小于等于3,由下图可以看出,把a构造为一个足够大的科学计数法数即可(9e9)
第二个判断是:
if(isset($b) && '8b184b' === substr(md5($b),-6,6))
substr函数简介如下图,值得注意的是strat为负数n时,起始位置是在字符串尾部向前的n位,但是之后仍然是向后取字符串。
这个判断要求b的md5值的最后六位等于‘8b184b',用代码进行爆破即可,得出的一个可用值为53724.
第三个判断前,对c进行了json_decode处理,所以在之后构造的c,先用json_encode进行处理。
$c=(array)json_decode(@$_GET['c']);
if(is_array($c) && !is_numeric(@$c["m"]) && $c["m"] > 2022)
这个判断首先要求c是数组,然后要求c["m"]不是数字而c["m"]又要大于2022,显然,这两个条件相互矛盾,但是在php中,字符串和数字比较时,字符串会截取第一个字母前的数字来进行比较,所以只要让c["m"]=“2023a”即可(此处a可以任意替换为字母)。
下一个判断为:
if(is_array(@$c["n"]) && count($c["n"]) == 2 && is_array($c["n"][0]))
所以c["n"] 要是一个数组,且长度为2,c["n"][0]也要是一数组。
$d = array_search("DGGJ", $c["n"]);
$d === false?die("no..."):NULL;
foreach($c["n"] as $key=>$val){
$val==="DGGJ"?die("no......"):NULL;
}
下一个判断中,array_search在c["n"]中搜索“DGGJ”,如果没有这个值那么判断失败,之后又遍历c["n"],如果找到DGGJ则判断同样失败,这又是两个互相矛盾的要求。
array_search的搜索过程中,使用的是“==”比较,所以“DGGJ”==0是成立的,因此,要保证在c["n"]中有0,即可绕过array_search的判断。可以构造出
$c = array("m" => "2023a","n" => array(array(),0));
随后将其用json_encode编码后,可以得到最后的输入:
a=9e9&b=53724&c={"m":"2023a","n":[[],0]}
最后成功得到答案