PHP反序列化
php类可能会包含一些特殊的函数叫magic函数,magic函数命名是以符号_
开头的,比如 __construct, __destruct, __toString, __sleep, __wakeup
等等。这些函数在某些情况下会自动调用,比如__construct
当一个对象创建时被调用,__destruct
当一个对象销毁时被调用,__toString
当一个对象被当作一个字符串使用。
php允许保存一个对象方便以后重用,这个过程被称为序列化。php 将数据序列化和反序列化其实就用到两个函数,serialize 和unserialize。
serialize() 把变量和它们的值编码成文本形式
unserialize() 恢复原先变量
一个例子:
<?php
class User
{
public $age = 0;
public $name = '';
public function PrintData()
{
echo 'User ' . $this->name . ' is ' . $this->age
. ' years old. <br />';
}
}
$usr = new User();
$usr->age = 20;
$usr->name = 'John';
$usr->PrintData();
echo serialize($usr);
?>
结果是:
O:4:"User":2:{s:3:"age";i:20;s:4:"name";s:4:"John";}
上面的是序列化后的,O表示对象,4表示对象名User长度,i表示int,s是string。
- a - array
- b - boolean
- d - double
- i - integer
- o - common object
- r - reference
- s - string
- C - custom object
- O - class
- N - null
- R - pointer reference
- U - unicode string
PHP反序列化漏洞
漏洞的根源在于unserialize()函数的参数可控。如果反序列化对象中存在魔术方法,而且魔术方法中的代码有能够被我们控制,漏洞就这样产生了,根据不同的代码可以导致各种攻击,如代码注入、SQL注入、目录遍历等等。