反序列化时有哪些魔术方法是可以作为一个入手点去找的
__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()
返回的对象又可以触发其自身的魔术方法,形成一个连锁反应