一:前置知识
1.三种修饰符
| 修饰符 | 类内部 | 子类 | 类外 |
|---|---|---|---|
public | ✅ | ✅ | ✅ |
protected | ✅ | ✅ | ❌ |
private | ✅ | ❌ | ❌ |
打勾代表能访问。在 PHP 里,不同权限的属性,序列化名字是不一样的:
| 属性定义 | 序列化里的名字 |
|---|---|
public $a | a |
protected $a | \0*\0a |
private $a | \0 类名\0a |
例如之前构造的 payload:
O:11:"ctfShowUser":3:{ s:8:"username";s:6:"xxxxxx"; s:8:"password";s:6:"xxxxxx"; s:5:"isVip";b:1; }
可以看到是直接写 username 和 password,这是因为那时候的定义的时候用的是 public。
而在这里定义时用的则是 private,因此最前面要加上类名。
2.普通方法名
'普通方法名'= 程序员自己随便起的函数名字,比如 abc、getInfo 等。这里区别于 php 的魔术方法,这些是不能改动的:
__construct// 构造函数__destruct// 析构函数__wakeup__toString
3.POP 链
**POP 链(Property-Oriented Programming)**是通过'控制对象的属性',利用已有类的魔术方法,在反序列化过程中自动执行危险代码。POP 链能存在的原因是因为有 unserialize() —— 自动创建对象和魔术方法 —— 自动执行。

