ISCC2017 自相矛盾(代码审计)

<?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对象。

需要达到的其中两个条件:

  1. bar1要求不是全数字且大于2016,赋值为2017a即可
  2. 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;
    }
}
  1. 首先保证$c[1]存在,
  2. 然后eregi()函数我们可以用%00截断
  3. strcmp比较是==弱类型比较,构造 $c[1]为字符串,可以和%00(空)匹配,后面arraystring进行strcmp比较的时候会返回一个null
  4. 然后让$c[0]=”isccctf2017”即可

Payload:
?iscc={"bar1":"2017a","bar2":[[1],2,3,4,0]}&cat[1][]=1&dog=%00&cat[0]="isccctf2017"

得到flag。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值