源码
1 |
|
分析源码
- 反序列化漏洞利用条件: ①unserialize()参数可控 ②存在可以利用的魔术方法。
- 推测通过反序列化漏洞最终通过 Read 类读取flag信息。
- 只要类中存在魔术方法就可以利用,至于实现了什么功能并不重要。
思路
- 通过修改Read类中的$var并通过file_get方法读flag文件,而file_get通过__invoke()触发。
- __invoke()触发条件: 尝试以函数形式调用对象。 借助: Test类的 \get()方法
- __get()触发条件: 尝试访问对象中不存在的属性。 借助: Show类的 \toString()方法
- __toString()触发条件: 尝试将对象当做字符串处理。 借助: Show类的 \wakeup()中的正则表达式。
- __wakeup()触发条件: unserialize()解序列之后自动调用。
PoC
1 |
|
总结
反序列化漏洞看似简单,其实一环扣一环挺有意思。主要还是魔术方法的触发条件要熟悉。
目前见到的魔术方法:
- __construct(): 对象创建时调用。注意 unserialize()解序列不会调用。
- __destruct(): 对象销毁时调用。销毁对象: unset()
- __wakeup(): unserialize()解序列后调用。
- __toString(): 当对象被当做字符串使用时调用。
- __sleep(): 当对象被serialize()序列化时调用。
- __invoke(): 当以函数形式使用对象时调用。
- __get(): 当访问对象中不存在的属性时调用。
PHP的魔术方法定义: 以两个下划线开头 __magicMethods() 。
源码中的 _show()并不是魔术方法,称为私有方法。