<?php

/*
--- HelloCTF - 反序列化靶场 关卡 8 : 构造函数和析构函数 --- 

HINT:注意顺序和次数

# -*- coding: utf-8 -*-
# @Author: 探姬(@ProbiusOfficial)
# @Date:   2024-07-01 20:30
# @Repo:   github.com/ProbiusOfficial/PHPSerialize-labs
# @email:  admin@hello-ctf.com
# @link:   hello-ctf.com

*/

global $destruct_flag;
global 
$construct_flag;
$destruct_flag 0;
$construct_flag 0;

class 
FLAG {
    public 
$class_name;
    public function 
__construct($class_name)
    {
        
$this->class_name $class_name;
        global 
$construct_flag;
        
$construct_flag++;
        echo 
"Constructor called " $construct_flag "<br>";
    }
    public function 
__destruct()
    {
        global 
$destruct_flag;
        
$destruct_flag++;
        echo 
"Destructor called " $destruct_flag "<br>";
    }
}

/*Object created*/
$demo = new FLAG('demo'); 

/*Object serialized*/
$s serialize($demo);

/*Object unserialized*/
$n unserialize($s); 

/*unserialized object destroyed*/
unset($n);

/*original object destroyed*/
unset($demo);

/*注意 此处为了方便演示为手动释放,一般情况下,当脚本运行完毕后,php会将未显式销毁的对象自动销毁,该行为也会调用析构函数*/

/*此外 还有比较特殊的情况: PHP的GC(垃圾回收机制)会在脚本运行时自动管理内存,销毁不被引用的对象:*/
new FLAG();

Object created:Constructor called 1
Object serialized: But Nothing Happen(:
Object unserialized:But nothing happened either):
serialized Object destroyed:Destructor called 1
original Object destroyed:Destructor called 2

This object ('new FLAG();') will be destroyed immediately because it is not assigned to any variable:Constructor called 2
Destructor called 3

Now Your Turn!, Try to get the flag!
<?php

class RELFLAG {

    public function 
__construct()
    {
        global 
$flag;
        
$flag 0;
        
$flag++;
        echo 
"Constructor called " $flag "<br>";
    }
    public function 
__destruct()
    {
        global 
$flag;
        
$flag++;
        echo 
"Destructor called " $flag "<br>";
    }
}

function 
check(){
    global 
$flag;
    if(
$flag 5){
        echo 
"HelloCTF{???}";
    }else{
        echo 
"Check Detected flag is "$flag;
    }
}

if (isset(
$_POST['code'])) {
    eval(
$_POST['code']);
    
check();
}