web9
上源代码
<?php include "flag.php"; show_source(__FILE__); $v1=0;$v2=0; $a=(array)json_decode(@$_GET['dcn']); if(is_array($a)){ is_numeric(@$a["d1"])?die("错误"):NULL; if(@$a["d1"]){ ($a["d1"]>2019)?$v1=1:NULL; } if(is_array(@$a["d2"])){ if(count($a["d2"])!==5 OR !is_array($a["d2"][0])) die("错误"); $pos = array_search("dcnctf", $a["a2"]); $pos===false?die("错误"):NULL; foreach($a["d2"] as $key=>$val){ $val==="dcnctf"?die("错误"):NULL; } $v2=1; } } if($v1 && $v2){ echo $flag; } ?>
添加注释解析
<?php //这里使用include函数包含‘flag.php' include "flag.php"; show_source(__FILE__); //定义v1,v2两个变量 初始值为0 $v1=0;$v2=0; //定义变量a用来接收GTE【’dcn']的值 并进行Json解码和强转成数组 $a=(array)json_decode(@$_GET['dcn']); //做一个if判断,变量a是否为数组 if(is_array($a)){ //如果$a["d1"]是数字 则显示为 错误 否则为 NULL is_numeric(@$a["d1"])?die("错误"):NULL; //如果$a["d1"]存在 if(@$a["d1"]){ //如果$a["d1"]大于2019 则$v1=1,否则NULL ($a["d1"]>2019)?$v1=1:NULL; } //如果$a["d2"]存在且为数组 if(is_array(@$a["d2"])){ //(如果数组$a["d2"]的总行数不等于5 或者 $a["d2"][0]不是数组 )则输出"错误"并结束 if(count($a["d2"])!==5 OR !is_array($a["d2"][0])) die("错误"); //查找$a["d2"]数组中是否存在dcnctf的键名,并赋值给$pos $pos = array_search("dcnctf", $a["a2"]); //如果pos恒等于假 返回 错误 并结束 $pos===false?die("错误"):NULL; //循环数组$a["d2"] $key 为每次循环数组的键 $val为每次循环数组的值 foreach($a["d2"] as $key=>$val){ //如果每次循环数组的的值恒等于"dcnctf" 则输出"错误"并结束程序 $val==="dcnctf"?die("错误"):NULL; } //给v2变量赋值 $v2=1; } } //如果 变量 v1 v2有值 则输出变量flag if($v1 && $v2){ echo $flag; } ?>
通过注释了解到,这里要拿到flag就必须使v1 v2成立,所以这里我们分别求值,然后再合在一起。
首先是v1的值
//定义变量a用来接收GTE【’dcn']的值 并进行Json解码和强转成数组 $a=(array)json_decode(@$_GET['dcn']); //做一个if判断,变量a是否为数组 if(is_array($a)){ //如果$a["d1"]是数字 则显示为 错误 否则为 NULL is_numeric(@$a["d1"])?die("错误"):NULL; //如果$a["d1"]存在 if(@$a["d1"]){ //如果$a["d1"]大于2019 则$v1=1,否则NULL ($a["d1"]>2019)?$v1=1:NULL; }
传入dcn,经过json构造数组,判断$a['d1']是否为纯数字,首先变量不能为纯数字,其次在数值判断上要大于2019,因此可以利用弱类型进行绕狗,即$a["d1"]=2020a。
然后是v2的值
//如果$a["d2"]存在且为数组 if(is_array(@$a["d2"])){ //(如果数组$a["d2"]的总行数不等于5 或者 $a["d2"][0]不是数组 )则输出"错误"并结束 if(count($a["d2"])!==5 OR !is_array($a["d2"][0])) die("错误"); //查找$a["d2"]数组中是否存在dcnctf的键名,并赋值给$pos $pos = array_search("dcnctf", $a["a2"]); //如果pos恒等于假 返回 错误 并结束 $pos===false?die("错误"):NULL; //循环数组$a["d2"] $key 为每次循环数组的键 $val为每次循环数组的值 foreach($a["d2"] as $key=>$val){ //如果每次循环数组的的值恒等于"dcnctf" 则输出"错误"并结束程序 $val==="dcnctf"?die("错误"):NULL; } //给v2变量赋值 $v2=1;
这里要求d2变量是一个数组,且元素个数为5个,第一个元素为数组,因此构造 $a["d2"]=[[],1,2,3,4]
获取flag
//如果 变量 v1 v2有值 则输出变量flag if($v1 && $v2){ echo $flag; }
既然上面的已经获取得到v1 v2.所以构造语句: 拿到flag
?dcn={"d1":"2020a","d2":[[],2,3,4,5],"a2":["dcnctf"]}