PHP反序列化
概念:
序列化就是将对象转换成字符串,反序列化相反,把字符串转换为对象。数据的格式的转换对象的序列化有利于对象的保存和传输,也可以让多个文件共享对象。
使用的函数:
序列化:serialize()
反序列化:unserialize()
演示(无类)
需要用在线的php代码在线测试,地址:https://www.dooccn.com/php/
首先定义一个变量KEY,然后给这个变量赋值,用序列化:serialize()函数输出这个变量
我们可以看到输出的结果,s是string代表的是字符串,16代表的是变量名长度,变量名也就是qingchaxiansheng。
再演示一个
这里i是int代表的是整型。
以上就是一个序列化的演示,接下来再看反序列化的演示,反序列化其实就是序列化的逆推。
再看整型的
PHP反序列化漏洞
漏洞原理:未对用户输入的序列化字符串进行检测,导致攻击者可以控制反序列化过程,从而导致代码执行,sql注入,目录遍历等不可控后果,在反序列化的过程中自动触发了某些魔术方法。当进行反序列化的时候就有可能会触发对象中的一些魔术方法。
注:反序列化本身没有没有漏洞
触发
unserialize()函数的变量可控,文件中存在可利用的类,类中有魔术方法:
_construct() //创建对象时触发
_destruct() //对象被销毁触发
_csll() //在对象上下文中调用不可访问的方法时触发
_callStatic() //在静态上下文中调用不可访问的方法时触发
_get() //用于从不可访问的属性读取数据
_set() //用于将数据写入不可访问的属性
_isset() //在不可访问的属性上调用isset()或empty()触发
_unset() //在不可访问的属性上使用unset()时触发
_invoke() //当脚本尝试将对象调用为函数时触发
简单列出一些常用的魔术方法。还有很多,大家可以自行搜索一下。
打靶
网鼎杯2020青龙大赛真题
地址:https://www.ctfhub.com/#/index
由题可知:
由题目命名和函数unserialize可以判断此题目考察的是反序列化知识点。
主要是获取flag--存储flag.php
先进行代码分析,看看代码说了什么,看这段代码
这段代码从下往上看,GET接收一个str参数,然后用is_valid进行检测,检测通过就将str进行反序列化,中间一段代码是is_valid的检测内容。最后一段代码执行完成以后,也就是销毁了,在销毁的时候触发了析构函数_destruct.然后析构函数就开始执行。如果op===2,则会强制让他转为1.
补
isset()函数用于检测变量是否已设置并且非 NULL,符合返回ture,不符合返回false
is_valid()函数检查对象变量是否已经实例化,即实例变量的值是否是个有效的对象。如果指定对象已经创建了对此案实例,那么IsValid()函数返回True,否则返回FALSE。如果参数obejctname的值为NULL,IsValid()函数返回NULL。
传入的op=1就执行write写入,如果为2,就执行读取,因为我们是要flag,所以肯定是要他执行读取。
_destruct函数对$this->op进行了=的判断,但是process函数中使用的是对$this->op进行判断。所以我们要绕过_destruct函数的判断,进入到process函数中的读取。这里使用字符串' 2'进行绕过。这样就可以执行读取。
因为最后一步是将str进行反序列化,我们传入的时候就应该是序列化。
传入到str,右键查看源代码。
感觉我解的也有点乱,大家主要是明白这个反序列化。