1.类和对象的概念
简单来说类是一个事物的定义,而对象则是抽象事物的实体化
2.php的访问修饰符
三大类访问修饰符:public公共的类内类外和子类都i可以访问
protected在类的内部和子类可以被调用,在类的外部不可调用
pritave只能在类的内部被调用
3.序列化的概念
将以数据或数组转为字符,在php语言中通常使用serialize()来调用
O:4:"test":5:{s:8:" test a1";s:4:"haha";s:5:" * a2";s:4:"dada";s:2:"a3";s:4:"sasa";s:1:"b";b:1;s:1:"c";i:123;}
例如这个被序列化的数据我解释一下每一个东西的作用
O:object表示这个项目;“4”表示类名的长度,即test;“5”表示这个项目有几个成员;s“8“表示为字符型数据和其长度;
每个不同的属性也有不同的属性名
Public(公有):被序列化时属性值为:属性名
Protected(受保护):被序列化时属性值为:\x00*\x00属性名
Private(私有):被序列化时属性值为:\x00类名\x00属性名
4.序列化的漏洞成因
网站会同队对用户输入的数据进行反序列化来判断其身份,在url返回进行反序列前进行按格式添加成员,这时候反序列化会把这个代码带上就导致网站会出现了错误i的判断
5.魔术方法
函数 对象生命周期
_construct() 构造函数创建对象时使用
_destruct() 类的析构函数,对象被销毁时触发
__call() 用对象不可访问、不存在的方法时触发
__callStatic() 在静态上下文中调用不可访问的方法时触发
_get() 调用不可访问、不存在的对象成员属性时触发
__set() 在给不可访问、不存在的对象成员属性赋值时触发
__isset() 当对不可访问属性调用isset()或empty()时触发
__unset() 在不可访问的属性上使用unset()时触发
__invoke() 把对象当初函数调用时触发
__sleep() 执行serialize()时,先会调用这个方法
__wakeup() 执行unserialize()时,先会调用这个方法
__toString() 把对象当成字符串调用时触发
__clone() 使用clone关键字拷贝完一个对象后触发
6.一些常见的漏洞
——wake up()绕过
注意:只使用一些PHP版本php5-php5.6.25、php7-php7.0.10;
在我们调用unserialize时如果实际成员属性小于序列化中表示成员数量的属性时;不会触发wake up,这就出现了漏洞如果我们此时创建一段代码使成员实际数量小于序列化的数量,就不能出发wakeup
O:+6绕过
一些题目代码会遇到O:6会终止程序,那么就用O;+6就可以处理掉这个问题(数字根据题目要求调整)
7.字符串逃逸
因为反序列化根据:}判断结尾,而为了安全序列化时的字符串替换为一些关键词来反序列化,就会导致一些成员的属性丢失,就可以在playroad中使字符串逃逸
8.ctf
在第一题的源码中因为destruct在对象销毁时会触发要拿到flag,需要用a(lly)构造system('cat/flag')
然后通过post传参传递相应的字符串
第二题:属于wake uprap绕过方法,只需要将序列化的字符串输出然后使是成员少于即可
第三题:分析源码construct会将addmin赋值为user,passwd赋值为123456,最后destruct运行时需符合if的条件才可以输出flag,所以需要改变admin和passwd的值,要获取flag直接改变construct即可