反序列化漏洞入门

Web安全学习路径 | 模块3 | 课程4

1. 引言

反序列化漏洞(Deserialization)是一种常见的Web应用程序漏洞,攻击者可以通过操纵序列化的数据来执行未经授权的操作。这种漏洞通常出现在处理用户提供的序列化数据时,可能导致远程代码执行、权限提升等严重后果。

学习目标: 理解序列化和反序列化的概念,掌握反序列化漏洞的原理和利用方法,学习有效的防御技术。

2. 序列化基础

2.1 什么是序列化

序列化是将数据结构或对象状态转换为可存储或传输的格式的过程。在Web应用中,序列化通常用于:

  • 存储对象状态
  • 传输数据
  • 缓存管理
  • 会话处理

2.2 PHP序列化示例

// PHP序列化示例 <?php class User { public $username; public $isAdmin; function __construct($username, $isAdmin = false) { $this->username = $username; $this->isAdmin = $isAdmin; } } $user = new User("admin", true); $serialized = serialize($user); echo $serialized; // O:4:"User":2:{s:8:"username";s:5:"admin";s:7:"isAdmin";b:1;} ?>

3. 漏洞类型

3.1 PHP反序列化漏洞

PHP中的反序列化漏洞通常与魔术方法有关:

// 易受攻击的PHP代码 <?php class FileHandler { public $filename; function __destruct() { if (file_exists($this->filename)) { unlink($this->filename); } } } $data = $_GET['data']; $obj = unserialize($data); ?> // 攻击payload O:11:"FileHandler":1:{s:8:"filename";s:10:"/etc/passwd";}

3.2 Java反序列化漏洞

Java中的反序列化漏洞通常与readObject方法有关:

// 易受攻击的Java代码 public class User implements Serializable { private String username; private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { in.defaultReadObject(); Runtime.getRuntime().exec("calc.exe"); } }

3.3 Python反序列化漏洞

Python中的反序列化漏洞通常与pickle模块有关:

// 易受攻击的Python代码 import pickle data = request.GET.get('data') obj = pickle.loads(data) # 攻击payload pickle.dumps({'__class__': '__main__.Command', 'command': 'id'})

4. 漏洞利用技术

4.1 魔术方法利用

利用PHP魔术方法执行代码:

// 攻击示例 class Evil { public $cmd; function __wakeup() { system($this->cmd); } } $payload = serialize(new Evil("id")); // O:4:"Evil":1:{s:3:"cmd";s:2:"id";}

4.2 对象注入

通过注入恶意对象实现攻击:

// 攻击示例 class Database { public $connection; function __construct() { $this->connection = new mysqli("localhost", "root", "", "test"); } } $payload = serialize(new Database()); // 可能导致数据库连接信息泄露

4.3 链式调用

利用对象之间的依赖关系构造攻击链:

// 攻击示例 class File { public $filename; } class Logger { public $file; function __destruct() { if (file_exists($this->file->filename)) { unlink($this->file->filename); } } } $file = new File(); $file->filename = "/etc/passwd"; $logger = new Logger(); $logger->file = $file; $payload = serialize($logger);

5. 防御措施

5.1 输入验证

严格验证反序列化的数据:

// 使用白名单验证 <?php $allowed_classes = ['User', 'Settings']; $data = $_GET['data']; $obj = unserialize($data, ['allowed_classes' => $allowed_classes]); ?>

5.2 数据签名

使用数字签名验证数据完整性:

// 使用HMAC签名 <?php $data = $_GET['data']; $signature = $_GET['signature']; if (hash_hmac('sha256', $data, 'secret_key') === $signature) { $obj = unserialize($data); } ?>

5.3 使用安全的序列化格式

使用JSON等安全的序列化格式:

// 使用JSON替代原生序列化 $data = json_decode($_GET['data'], true); if (json_last_error() === JSON_ERROR_NONE) { // 处理数据 }

6. 实践练习

反序列化漏洞实战演练

在我们的靶场环境中,你可以安全地练习反序列化漏洞的发现和利用。点击下面的按钮开始练习:

开始练习