序列化serialize():
序列化说通俗点就是把一个对象变成可以传输的字符串

反序列化unserialize():
就是把被序列化的字符串还原为对象,然后在接下来的代码中继续使用。

序列化和反序列化本身没有问题,但是如果反序列化的内容是用户可以控制的,且后台不正当的使用了PHP中的魔法函数,就会导致安全问题


常见的几个魔法函数:
__construct()当一个对象创建时被调用

__destruct()当一个对象销毁时被调用

__toString()当一个对象被当作一个字符串使用

__sleep() 在对象在被序列化之前运行

__wakeup将在序列化之后立即被调用


class S{
var $test = “pikachu”;
function __destruct(){
echo $this->test;
}
}
$s = $_GET[‘test’];
@$unser = unserialize($a);

payload:O:1:”S”:1:{s:4:”test”;s:29:”“;}

(没找到phpstudy/www/pikachu/test/ser.php)


xss可以正常弹出

例如:
O:3:"Ctf":3{s:4:"flag";s:13:"flag{abedyui}";s:4:"name";s:7:"Sch0lar";s:3:"age";s:2:"18";}
O代表对象 因为我们序列化的是一个对象 序列化数组则用A来表示
3 代表类名字占三个字符
ctf 类名
3 代表三个属性
s代表字符串
4代表属性名长度
flag属性名
s:13:”flag{abedyui}” 字符串 属性值长度 属性值


根据访问控制修饰符的不同 序列化后的 属性长度和属性值会有所不同:
public(公有)
protected(受保护)
private(私有的)
protected属性被序列化的时候属性值会变成:%00*%00属性名
private属性被序列化的时候属性值会变成:%00类名%00属性名
如:
O:4:"Name":2:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}
//这里是private属性被序列化


绕过wakeup()函数:
当序列化字符串表示对象属性个数的值大于真实个数的属性时就会跳过wakeup的执行。(根据上面代码修改 name:3)
O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}
CTF中的序列化与反序列化