您好,登录后才能下订单哦!
# PHP反序列化的原理
## 1. 序列化与反序列化基础概念
### 1.1 什么是序列化
序列化(Serialization)是将数据结构或对象状态转换为可存储或可传输格式的过程。在PHP中,序列化后的数据是一个包含字节流的字符串,它可以保存对象的属性、类型和结构信息。
```php
class User {
public $username = 'admin';
protected $password = '123456';
private $salt = 'abc';
}
$user = new User();
echo serialize($user);
// 输出:O:4:"User":3:{s:8:"username";s:5:"admin";s:11:"*password";s:6:"123456";s:10:"Usersalt";s:3:"abc";}
反序列化(Unserialization)是将序列化后的字符串还原为原始数据结构或对象的过程。这是序列化的逆操作。
$serialized = 'O:4:"User":3:{...}';
$unserialized = unserialize($serialized);
var_dump($unserialized);
PHP序列化字符串包含以下关键部分:
类型标识符:
a
- arrayO
- objects
- stringi
- integerd
- doubleb
- booleanN
- null对象序列化格式:
O:<类名长度>:"<类名>":<属性数量>:{<属性序列化>...}
属性序列化规则:
s:<长度>:"<属性名>";<值>
s:<长度>:"\0*\0<属性名>";<值>
s:<长度>:"\0<类名>\0<属性名>";<值>
unserialize()
函数内部实现主要步骤:
php_var_unserialize()
开始解析unserialize_obj()
处理zend_lookup_class()
查找类定义object_common1()
初始化对象__wakeup()
PHP提供了一些在反序列化过程中自动调用的魔术方法:
在对象反序列化完成后立即调用:
class User {
public function __wakeup() {
echo "Wake up called!\n";
}
}
当对象被销毁时调用:
class User {
public function __destruct() {
echo "Destructor called!\n";
}
}
在序列化时调用,可指定需要序列化的属性:
class User {
public function __sleep() {
return ['username']; // 只序列化username属性
}
}
class VulnerableClass {
public $file;
public function __destruct() {
if(file_exists($this->file)) {
unlink($this->file);
}
}
}
// 攻击者可构造恶意序列化数据
$payload = 'O:15:"VulnerableClass":1:{s:4:"file";s:9:"important.txt";}';
unserialize($payload);
通过修改序列化字符串中的属性数量,可以绕过__wakeup()
的执行:
// 原始序列化数据
O:4:"User":1:{s:8:"username";s:5:"admin";}
// 修改属性数量后的payload
O:4:"User":100:{s:8:"username";s:5:"admin";}
Property-Oriented Programming(面向属性编程)通过组合不同类的魔术方法和普通方法,形成可执行任意代码的调用链。
class Gadget1 {
public $handle;
public function __destruct() {
$this->handle->close();
}
}
class Gadget2 {
public $filename;
public function close() {
eval(file_get_contents($this->filename));
}
}
// 构造恶意序列化数据
$payload = serialize([
new Gadget1(),
new Gadget2()
]);
unserialize_callback_func
指定回调函数allowed_classes
限制可反序列化的类:unserialize($data, ['allowed_classes' => ['SafeClass']]);
__sleep()
限制序列化的属性漏洞位于install.php
中,通过反序列化Referer
头实现RCE:
$config = unserialize(base64_decode(Typecho_Cookie::get('__typecho_config')));
利用Ignition组件的反序列化漏洞,通过精心构造的日志文件实现远程代码执行。
unserialize()
调用PHP反序列化是一个强大的功能,但也带来了严重的安全风险。理解其底层原理对于开发安全的应用程序至关重要。开发者应当:
通过正确理解和使用反序列化机制,可以在享受其便利性的同时有效降低安全风险。 “`
这篇文章共计约2300字,详细介绍了PHP反序列化的核心原理、安全风险及防御措施,采用Markdown格式编写,包含代码示例和结构化标题。内容涵盖从基础概念到高级利用技术的完整知识体系。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。