一、介绍
这两个方法是在对象的序列化与反序列话里使用的,当序列化serialize对象时,可以把对象里的属性和方法转换成连续的bytes数据,保存在一个文件里或者在网络上传输,当需要使用这个对象时,就可以反序列话unserialize这个字符串,得到这个对象,然后继续使用。
当对一个对象序列化时,php就会调用__sleep方法(如果存在的话),在反序列化时,php就会调用__wakeup方法(如果存在的话)。__sleep这个方法可以用于清理对象,并返回一个包含对象中所有变量名称的数组。如果该方法不返回任何内容,则NULL被序列化,导致一个E_NOTICE错误。在反序列化unserialize时,会检查是否存在__wakeup方法,如果存在,则会调用__wakeup方法,预先准备对象数据。
__sleep() 方法常用于提交未提交的数据,或类似的清理操作。同时,如果有一些很大的对象,但不需要全部保存,这个功能就很好用。__wakeup 经常用在反序列化操作中,例如重新建立数据库连接,或执行其它初始化操作。
二、__wakeup()函数漏洞
1. _wakeup()执行漏洞:一个字符串或对象被序列化后,如果其属性被修改,则不会执行__wakeup()函数。
2.通过精心构造poc,还可以通过反序列化控制实例对象中属性的内容,从而实现代码执行。(详见:freebuf专栏)
更多详细解释移步freebuf:https://www.freebuf.com/articles/web/167721.html
三、关于利用
一般都是对一个已实例化的对象中的内容需要保存,为了节省开发成本,选择序列化之后保存该序列化字符串,等到后面使用的时候,再恢复为对象实例。类似json的序列化!
序列化之后的结果就是一串字符串,在恢复的时候,会检测其属性个数与类模板中的类型个数是否相同,类型不同,属性增多都会导致反序列化失败,也就是不执行魔术函数。
因此,可以构造序列化内容,修改其中属性类型或个数,从而进行绕过对应的magic函数。来拿到flag
四、注意
属性:指的是变量,包括字符串,类,数组,数字等等。 不包括函数!!!