github编辑

[网鼎杯 2020 青龙组]AreUSerialz

[网鼎杯 2020 青龙组]AreUSerialz

考点

  • 逻辑漏洞,两次比较方式不一样,一个强比较一个弱比较

  • PHP在7.1版本以上属性类型不敏感,在序列化时候把属性改为public就可以绕过

  • __destruct()中读取文件用绝对路径

wp

给了代码,先看入口

function is_valid($s) {
    for($i = 0; $i < strlen($s); $i++)
        if(!(ord($s[$i]) >= 32 && ord($s[$i]) <= 125))
            return false;
    return true;
}

if(isset($_GET{'str'})) {

    $str = (string)$_GET['str'];
    if(is_valid($str)) {
        $obj = unserialize($str);
    }
}

传入参数str,使用is_valid()判断是否满足条件,满足条件就对它反序列化。条件是str中字符的范围要在[32, 125]内。

然后再看给的FileHandler类,从__destruct()开始,然后对属性值做改变,最后执行process()函数

然后看process()函数,其中又调用了write()read()output()函数

write()函数向$this->filename中写入$this->content

read()函数读取$this->filename

output()函数输出字符串

再看process()函数,如果$this->op1,就是写入文件,$this->op2就是读取文件并输出,否则就输出Bad Hacker

__destruct()$this->op的判断使用的==="2"强等于,而在process()$this->op的判断使用的=="2"弱等于,可以使用int型的2绕过

得到结果如下,但是protected属性在序列化时会加上%00,这不符合输入要求。PHP在7.1版本以上属性类型不敏感,在序列化时候把属性改为public就可以绕过

F12可以看到flag,原题是先读取/proc/self/目录找到配置文件,再去读flag,注意是用绝对路径。

小结

  1. 细节很重要

最后更新于