序列化和反序列化
序列化:把对象转换为字节序列的过程,即把对象转换为可以存储或传输的数据的过程。
反序列化:把字节序列恢复为对象的过程,即把可以存储或传输的数据转换为对象的过程。

原理:未对用户输入的序列化字符串进行检测,导致攻击者可以控制反序列化过程,从而导致代码执行,SQL注入,目录遍历等不可控后果。
漏洞可能出现的位置
解析认证token、session的位置
将序列化的对象存储到磁盘文件或存入数据库后反序列化时的位置,如读取json文件,xml文件等
将对象序列化后在网络中传输,如传输json数据,xml数据等
参数传递给程序
使用RMI协议,被广泛使用的RMI协议完全基于序列化
使用了不安全的框架或基础类库,如JMX 、Fastjson和Jackson等
定义协议用来接收与发送原始的java对象
PHP中的系列化和反序列化
PHP中常用魔术方法
serialize() //将一个对象转换成一个字符串
unserialize() //将字符串还原成一个对象
__construct() //创建对象时触发
__destruct() //对象被销毁时触发
__call() //在对象上下文中调用不可访问的方法时触发
__callStatic() //在静态上下文中调用不可访问的方法时触发
__get() //用于从不可访问的属性读取数据
__set() //用于将数据写入不可访问的属性
__isset() //在不可访问的属性上调用isset()或empty()触发
__unset() //在不可访问的属性上使用unset()时触发
__invoke() //当脚本尝试将对象调用为函数时触发
漏洞演示:
<?php
class demo{
var $name = "calc";
function __destruct(){
print "Execute CMD: ".$this->name."<br/>";
print "Result: ";
system($this->name);
print "<br/>";
}
}
// 实例化一个对象a
$a=new demo();
// 序列化对象a
print "Serialize Object A: ".serialize($a)."<br/>";
// GET方式获取参数arg的值
$arg = $_GET['arg'];
// 反序列化参数arg的值
$a_unser = unserialize($arg);
?>

成功打开计算器。