php
反序列化 #
序列化其实就是将数据转化成一种可逆的数据结构,自然,逆向的过程就叫做反序列化。
两个函数
serialize 将对象格式化成有序的字符串
unserialize 将字符串还原成原来的对象
<?php
class test{
public $a;
public $b;
function __construct(){$this->a = "xiaoshizi";$this->b="laoshizi";}
function happy(){return $this->a;}
}
$a = new test();
echo serialize($a);
?>
输出
O:4:"test":2:{s:1:"a";s:9:"xiaoshizi";s:1:"b";s:8:"laoshizi";}
序列化后字符串的格式
O:4:"对象名":变量数量:{s:变量名长度:"变量名";s:变量值长度:"变量值";s:1:"b";s:8:"laoshizi";}
修饰符 #
如果变量前的修饰符是protected或private,先将代码的修饰符改为public进行序列化,再做修改
private =>%00class_name%00name 长度+类名长度+2
protected =>%00*%00name 长度+3
php7.1+不敏感
常见的魔术方法
__wakeup() //执行unserialize()时,先会调用这个函数
__sleep() //执行serialize()时,先会调用这个函数
__destruct() //对象被销毁时触发
__call() //在对象上下文中调用不可访问的方法时触发
__callStatic() //在静态上下文中调用不可访问的方法时触发
__get() //用于从不可访问的属性读取数据或者不存在这个键都会调用此方法
__set() //用于将数据写入不可访问的属性
__isset() //在不可访问的属性上调用isset()或empty()触发
__unset() //在不可访问的属性上使用unset()时触发
__toString() //把类当作字符串使用时触发
__invoke() //当尝试将对象调用为函数时触发
字符串逃逸 #
<?php
function repl($s){
return str_replace('flag', 'hack!', $s);
}
class A{
public $user='admin';
public $pwd='123456';
}
$a=new A();
$u=serialize($a);
echo $u.' ';
$b=unserialize($u);
echo $b->user.' '.$b->pwd;
?>
输出,没问题
...