原理:未对用户输入的序列化字符串进行检测,导致攻击者可以控制反序列化过程,从而导致代码执行,SQL 注入,目录遍历等不可控后果。在反序列化的过程中自动触发了某些魔术方法。当进行反序列化的时候就有可能会触发对象中的一些魔术方法。
serialize() //将一个对象转换成一个字符串
unserialize() //将字符串还原成一个对象
serialize()序列化输出:
$key="chen";
echo serialize($key); s:4:"chen";
__construct()//创建对象时触发
__destruct() //对象被销毁时触发
__call() //在对象上下文中调用不可访问的方法时触发
__callStatic() //在静态上下文中调用不可访问的方法时触发
__get() //用于从不可访问的属性读取数据
__set() //用于将数据写入不可访问的属性
__isset() //在不可访问的属性上调用isset()或empty()触发
__unset() //在不可访问的属性上使用unset()时触发
__invoke() //当脚本尝试将对象调用为函数时触发
例:
<?php
error_reporting(0);
include "flag.php";
$KEY = "xiaodi";
$str = $_GET['str'];
if (unserialize($str) === "$KEY")
{
echo "$flag";
}
show_source(__FILE__);
class ABC{
public $test;
function __construct(){
$test =1;
echo '调用了构造函数<br>';
}
function __destruct(){
echo '调用了析构函数<br>';
}
function __wakeup(){
echo '调用了苏醒函数<br>';
}
}
echo '创建对象a<br>';
$a = new ABC;
$a_ser='O:3:"ABC":2:{s:4:"test";s:8:"flog.php";s:2:"op";s:2:" 2";}';
echo '反序列化<br>';
echo '序列化<br>';
$a_ser=serialize($a);
echo '反序列化<br>';
$a_unser = unserialize($a_ser);
echo '对象结束';
?>