是时候重新回到学习状态。
继续学习php的魔术方法,很多都是当某个操作失败时(或者调用不存在的东西)触发这些魔术方法,也有某些操作会触发魔术方法,这是默认的,如果没有配置好,攻击者可以利用魔术方法来设计攻击方法。
下面是上一篇关于php的魔术方法:
触发:unserialize函数的变量可控,文件中存在可利用的类,类中有魔术方法:
__construct(): //构造函数,当对象new的时候会自动调用
__destruct()://析构函数当对象被销毁时会被自动调用
__wakeup(): //unserialize()时会被自动调用
__invoke(): //当尝试以调用函数的方法调用一个对象时,会被自动调用
__call(): //在对象上下文中调用不可访问的方法时触发
__callStatci(): //在静态上下文中调用不可访问的方法时触发
__get(): //用于从不可访问的属性读取数据
__set(): //用于将数据写入不可访问的属性
__isset(): //在不可访问的属性上调用isset()或empty()触发
__unset(): //在不可访问的属性上使用unset()时触发
__toString(): //把类当作字符串使用时触发
__sleep(): //serialize()函数会检查类中是否存在一个魔术方法__sleep() 如果存在,该方法会被优先调用
对象变量属性:
public(公共的):在本类内部、外部类、子类都可以访问
protect(受保护的):只有本类或子类或父类中可以访问
private(私人的):只有本类内部可以使用
序列化数据显示:
private属性序列化的时候格式是%00类名%00成员名
protect属性序列化的时候格式是%00*%00成员名
从序列化的字符串,可以判断,序列化前对象变量的属性,如下,当变量属性是public时,序列化显示正常:

序列化后:O:4:”test”:3:{s:4:”name”:s:6:”xiaodi”;}
如果对象属性是private,则会变成%00类名%00成员名,注意到%00会被识别为类似c语言的null,序列化之后存在但是看不见,效果如下:
序列化后:O:4:”test”:3:{s:4:”name”:s:6:”xiaodi”;s:9(7+2,2是两个%00):”testage”;} //testage就是类名加成员名。经常在序列化后要编码,因为不编码的话%00会操作不到。
那么,如果属性是protect的话就会是%00*%00,序列化之后如下:
序列化后:O:4:”test”:3:{s:4:”name”:s:6:”xiaodi”;s:9:”testage”;s:2:”29″;s:6:”*sex”:s:3:”man”;} //高亮处S为6是因为两个%00和*也算进去了。
反序列化在很多ctf比赛上有,依稀记得很久之前某次面试面试官让我手撕一个对象序列化之后的字符串,当时要是早点学就好了。反序列化除了利用逻辑漏洞,还可以利用语言漏洞,比如php的漏洞。在某道ctf题目中,需要对_wakeup()进行绕过,具体使用CVE-2016-7124,利用原理是构造payload中,修改变量个数超过正确个数,注意要进行urlencode编码。
PHP原生类学习:
每个魔术方法的原生类不一样,起到的效果不一样。
phar
字符串逃逸
session