题目分析
题目信息如下:
相关知识
- 序列化是将对象、数组、类、变量转化为字符串,以便记录他们的状态。反序列化就是将字符串再转换为对象、数组、类、变量。
- 一个对象或者类经过序列化之后的格式:
O:<length>:"<class name>":<n>:{<field name 1><field value 1>...<field name n><field value n>}
O:表示序列化的事对象
< length>:表示序列化的类名称长度
< class name>:表示序列化的类的名称
< n >:表示被序列化的对象的属性个数
< field name 1>:属性名
< field value 1>:属性值O:表示序列化的事对象
< length>:表示序列化的类名称长度
< class name>:表示序列化的类的名称
< n >:表示被序列化的对象的属性个数
< field name 1>:属性名
< field value 1>:属性值
一旦unserialize函数执行的变量可控了,就容易产生反序列化漏洞。
当unserialize函数执行的变量可控时,会容易产生反序列化漏洞,原因如下:
可控变量的恶意构造:通过控制可被unserialize函数执行的变量,攻击者可以构造恶意的序列化数据,利用序列化数据中的特定结构和内容来执行非预期的操作。这可能导致解序列化后恶意代码的执行,从而造成安全漏洞。
安全性不可控:unserialize函数对于输入的可控变量缺乏足够的验证和过滤,导致恶意用户可以通过构造特定的数据来绕过原有的安全检查,使得系统变得不可预测和不安全。
信任关系破坏:一旦将可控变量传递给unserialize函数,就意味着程序对该数据的信任关系被破坏。攻击者可以利用这一点来执行各种攻击,包括代码注入、远程命令执行等。
因此,即使在一开始设计上没有直接的漏洞,但一旦允许可控变量影响unserialize函数的执行,就会增加系统的安全风险。为了防止反序列化漏洞,建议在使用unserialize函数时进行严格的输入验证和过滤,以及采取其他安全防护措施,以确保不会受到恶意序列化数据的影响。
解题过程
通过unserialize这个题目名称和 class 这样的敏感词汇,得出这是一个反序列化的题目。 class这个类当中,有变量flag,看样子应该在这里找到flag。 但是后面的语句表明,new一个xctf的类时,执行了 __wakeup中的 exit,也就是new了这个类,就直接退出了。下面的?code是提示给我们的传参点,也就是将unserialize执行的代码通过code传过去。
使用php在线编辑器
先进行反序列化
__wakeup()函数存在一个漏洞。 __wakeup函数触发于unserialize()函数之前。但是如果被反序列话的字符串其中对应的对象的属性个数发生变化时,会导致反序列化失败而同时使得__wakeup失效。
把类new一个之后,再执行序列化得到的结果如下。