文章目录
- 一、序列化与反序列化
- 二、PHP反序列化漏洞成因
- 三、JAVA反序列化
一、序列化与反序列化
在PHP语言开发层面上基本都是围绕着serialize(),unserialize()这两个函数。serialize()函数序列化对象后,可以很方便的将它传递给其他需要它的地方,且其类型和结构不会改变。
语法:string serialize(mixed $value)
实例:可通过链接进行测试 -> 点击进入
<?php
$a = array('a' => 'admin' ,'b' => 'boss' , 'c' =>'cookie'); //序列化数组
$s = serialize($a);
echo $s;
?>
unserialize()函数用于将通过serialize()函数序列化后的对象或数组进行反序列化,并返回原始的对象结构。
语法:mixed unserialize(string $str)
实例:可通过链接进行测试 -> 点击进入
<?php
$str = 'a:3:{s:1:"a";s:5:"admin";s:1:"b";s:4:"boss";s:1:"c";s:6:"cookie";}';
$unserialized_data = unserialize($str);
print_r($unserialized_data);
?>
php允许保存一个对象方便以后重用,这个过程被称为序列化。在传递变量的过程中,有可能遇到变量值要跨脚本文件传递的过程。试想,如果在一个脚本中想要调用之前一个脚本的变量,但是前一个脚本已经执行完毕,所有的变量和内容释放掉了,我们要如何操作呢?难道要前一个脚本不断的循环,等待后面脚本调用?这肯定是不现实的。serialize和unserialize就是用来解决这一问题的。serialize可以将变量转换为字符串并且在转换中可以保存当前变量的值;unserialize则可以将serialize生成的字符串变换回变量。
二、PHP反序列化漏洞成因
PHP类中有一种特殊函数体的存在叫魔法函数,magic
函数命名是以符号开头的,比如construct
,destruct
,toString
,sleep
,wakeup
等等。这些函数在某些情况下会自动调用。而在反序列化时,如果反序列化对象中存在魔法函数,使用unserialize()
函数同时也会触发。这样,一旦我们能够控制unserialize()
入口,那么就可能引发对象注入漏洞。
construct():当一个类被创建时自动调用
destruct():当一个类被销毁时自动调用
invoke():当把一个类当作函数使用时自动调用
tostring():当把一个类当作字符串使用时自动调用
wakeup():当调用unserialize()函数时自动调用
sleep():当调用serialize()函数时自动调用
__call():当要调用的方法不存在或权限不足时自动调用
三、JAVA反序列化
序列化是让Java对象脱离Java运行环境的一种手段,可以有效的实现多平台之间的通信、对象持久化存储。Java序列化是指把Java对象转换为字节序列的过程便于保存在内存
、文件
、数据库
中,ObjectOutputStream
类的writeObject()
方法可以实现序列化。反序列化是指把字节序列恢复为Java对象的过程,ObjectInputStream
类的readObject()
方法用于反序列化。漏洞成因序列化和反序列化本身并不存在问题。但当输入的反序列化的数据可被用户控制,那么攻击者即可通过构造恶意输入,让反序列化产生非预期的对象,在此过程中执行构造的任意代码。
待补充…