### 反序列化时有哪些魔术方法是可以作为一个入手点去找的

**`__wakeup()`**

当`unserialize()`函数被调用时，`__wakeup()` 方法会立即被调用。这个方法通常用于在对象被反序列化后重新建立其内部状态。

- **攻击思路：** 攻击者可以寻找 `__wakeup()` 方法中是否存在**危险函数调用**（例如 `system()`、`eval()` 等），或者其内部逻辑是否可控，从而导致一些意想不到的后果

**`__destruct()`**

当一个对象被销毁时（例如脚本执行结束或对象被显式释放），`__destruct()` 方法会被调用

- **攻击思路：** `__destruct()` 是攻击者最喜欢的入手点之一，因为它**总是在脚本执行的最后被调用**，无论反序列化过程是否成功。如果该方法中存在文件删除、命令执行或其他敏感操作，攻击者可以通过构造恶意序列化字符串来触发它，从而达到攻击目的

**`__toString()`**

当一个对象被当作字符串使用时，`__toString()`方法会被自动调用

- **攻击思路：** 攻击者可以寻找哪些函数会将对象作为字符串处理。例如，`echo`、`print`、`file_get_contents()`等函数都会触发 `__toString()`。如果该方法中包含敏感操作，或者可以将 `__toString()` 的返回值作为参数传递给其他危险函数，就可能导致漏洞。这通常被称为“**POP链**”中的一个重要环节

**`__call()`**

当一个对象中不存在某个方法，但你却试图调用它时，`__call()` 方法会被自动调用

- **攻击思路：** `__call()`可以用来触发其他方法。如果 `__call()` 方法能够通过某种方式调用到危险方法，攻击者就可以通过调用一个不存在的方法来间接触发漏洞

**`__callStatic()`**

与 `__call()` 类似，但它在调用一个不存在的静态方法时触发

- **攻击思路：** 同样可以用于触发类中的敏感静态方法

**`__get()` 和 `__set()`**

当试图访问一个不存在的或不可访问的属性时，`__get()` 会被调用。当试图给一个不存在的或不可访问的属性赋值时，`__set()` 会被调用

- **攻击思路：** 这两个方法经常用于创建所谓的“**属性链**”。通过控制 `__get()` 或 `__set()` 中的逻辑，可以间接控制其他对象的属性或触发其他方法。例如，`__get()` 返回的对象又可以触发其自身的魔术方法，形成一个连锁反应