高级漏洞篇之不安全的反序列化专题
字数 1991 2025-08-10 16:34:36

不安全的反序列化漏洞深度解析

序列化与反序列化基础概念

什么是序列化

序列化是将复杂数据结构(如对象)转换为可传输或存储的扁平化格式的过程。序列化后的数据可以:

  • 写入进程间内存、文件或数据库
  • 通过网络或API在不同组件间传输
  • 持久化保存对象的状态、属性和值

什么是反序列化

反序列化是序列化的逆向操作,将序列化数据还原为原始对象,恢复其状态及属性值。

不同语言的序列化实现

  • PHP:使用serialize()unserialize()函数,序列化格式为JSON字符串
  • Java:二进制格式,序列化对象以ac(十六进制)或rO0(Base64)开头
  • Ruby:称为"marshalling"
  • Python:称为"pickling"

不安全的反序列化漏洞原理

漏洞成因

应用程序过度信任用户提供的序列化数据,在反序列化前未进行充分验证,导致攻击者可以通过精心构造的序列化数据执行恶意操作。

漏洞危害

  • 可能在反序列化完成前就触发攻击
  • 可导致权限提升、任意文件删除、远程代码执行等高危后果
  • 利用复杂度高但危害极大

漏洞利用技术

1. 修改对象属性

示例
原始序列化数据:

O:4:"User":2:{s:8:"username";s:6:"carlos";s:7:"isAdmin";b:0;}

修改为:

O:4:"User":2:{s:8:"username";s:6:"carlos";s:7:"isAdmin";b:1;}

利用场景:当应用程序仅检查isAdmin属性来判断用户权限时。

2. 修改数据类型

利用弱类型比较特性(如PHP的==):

  • 5 == "5" → true
  • 5 == "5 of something" → true
  • 0 == "Example string" → true

示例利用代码

$login = unserialize($_COOKIE)
if ($login['password'] == $password) {
    // log in successfully
}

攻击方法:设置密码为任意字符串,输入0即可绕过验证。

3. 利用应用程序功能点

通过修改序列化数据中的属性,利用应用程序现有功能实现攻击。例如:

  • 修改image_location属性导致删除任意文件
  • 修改数据库查询参数导致SQL注入

4. 魔术方法利用

魔术方法是在特定情况下自动调用的方法,常见于面向对象语言中:

PHP魔术方法

  • __construct():对象实例化时调用
  • __destruct():对象销毁时调用
  • __wakeup():反序列化时调用

Java特殊方法

  • readObject():从字节流反序列化时调用

利用方式:通过重写这些方法,在反序列化过程中执行恶意代码。

5. 工具链(Gadget Chains)利用

当单个魔术方法不足以完成攻击时,需要构造一系列方法调用的链条。

现有工具:

  • ysoserial:Java反序列化利用工具

    • 常用链:URLDNS(检测漏洞)、JRMPClient(检测漏洞)、CommonsCollections(RCE)
  • PHPGGC:PHP通用工具链利用工具

自定义工具链构建步骤:

  1. 分析应用程序源码
  2. 寻找可利用的魔术方法和对象属性
  3. 构造调用链实现恶意操作

6. PHAR反序列化(PHP特有)

利用PHP的phar://协议处理.phar文件时的反序列化操作:

  1. 构造恶意.phar文件
  2. 通过文件上传等方式将其传至服务器
  3. 使用phar://协议触发反序列化

漏洞检测方法

  1. Java

    • 查找以rO0开头的Base64数据
    • 使用URLDNS或JRMPClient链检测
  2. PHP

    • 查找明显的序列化字符串格式
    • 搜索unserialize()函数调用
  3. 通用方法

    • 修改序列化数据观察应用程序行为
    • 监控异常网络请求(DNS/HTTP)

漏洞防御措施

  1. 避免使用反序列化:尽可能使用其他数据交换格式
  2. 严格验证输入:在反序列化前验证数据完整性和签名
  3. 限制反序列化类:使用白名单限制可反序列化的类
  4. 日志与监控:记录反序列化操作并监控异常
  5. 代码审计:检查所有反序列化点及魔术方法

实战案例解析

案例1:Java反序列化导致SQL注入

  1. 发现备份文件泄露数据库配置
  2. 分析源码发现SQL拼接漏洞
  3. 构造包含SQL注入payload的序列化对象
  4. 通过反序列化触发注入获取管理员凭证

案例2:PHP魔术方法链实现RCE

  1. 分析源码发现__destruct删除文件功能
  2. 构造调用链:
    • CustomTemplate->desc设置为DefaultMap实例
    • DefaultMap->callback设置为exec
    • 通过__get魔术方法调用exec
  3. 实现任意命令执行

案例3:PHAR反序列化利用

  1. 发现文件上传功能
  2. 构造恶意.phar文件伪装为图片上传
  3. 通过phar://协议触发反序列化
  4. 利用SSTI(服务器端模板注入)执行命令

总结

不安全的反序列化是Web安全中的高危漏洞,理解其原理和利用技术对安全从业者至关重要。防御需要从代码设计、输入验证和运行时保护等多层面入手。随着应用程序复杂度增加,反序列化漏洞的利用方式也在不断演变,需要持续关注最新的研究和防护技术。

不安全的反序列化漏洞深度解析 序列化与反序列化基础概念 什么是序列化 序列化是将复杂数据结构(如对象)转换为可传输或存储的扁平化格式的过程。序列化后的数据可以: 写入进程间内存、文件或数据库 通过网络或API在不同组件间传输 持久化保存对象的状态、属性和值 什么是反序列化 反序列化是序列化的逆向操作,将序列化数据还原为原始对象,恢复其状态及属性值。 不同语言的序列化实现 PHP :使用 serialize() 和 unserialize() 函数,序列化格式为JSON字符串 Java :二进制格式,序列化对象以 ac (十六进制)或 rO0 (Base64)开头 Ruby :称为"marshalling" Python :称为"pickling" 不安全的反序列化漏洞原理 漏洞成因 应用程序过度信任用户提供的序列化数据,在反序列化前未进行充分验证,导致攻击者可以通过精心构造的序列化数据执行恶意操作。 漏洞危害 可能在反序列化完成前就触发攻击 可导致权限提升、任意文件删除、远程代码执行等高危后果 利用复杂度高但危害极大 漏洞利用技术 1. 修改对象属性 示例 : 原始序列化数据: 修改为: 利用场景 :当应用程序仅检查 isAdmin 属性来判断用户权限时。 2. 修改数据类型 利用弱类型比较特性(如PHP的 == ): 5 == "5" → true 5 == "5 of something" → true 0 == "Example string" → true 示例利用代码 : 攻击方法:设置密码为任意字符串,输入0即可绕过验证。 3. 利用应用程序功能点 通过修改序列化数据中的属性,利用应用程序现有功能实现攻击。例如: 修改 image_location 属性导致删除任意文件 修改数据库查询参数导致SQL注入 4. 魔术方法利用 魔术方法是在特定情况下自动调用的方法,常见于面向对象语言中: PHP魔术方法 : __construct() :对象实例化时调用 __destruct() :对象销毁时调用 __wakeup() :反序列化时调用 Java特殊方法 : readObject() :从字节流反序列化时调用 利用方式 :通过重写这些方法,在反序列化过程中执行恶意代码。 5. 工具链(Gadget Chains)利用 当单个魔术方法不足以完成攻击时,需要构造一系列方法调用的链条。 现有工具: ysoserial :Java反序列化利用工具 常用链:URLDNS(检测漏洞)、JRMPClient(检测漏洞)、CommonsCollections(RCE) PHPGGC :PHP通用工具链利用工具 自定义工具链构建步骤: 分析应用程序源码 寻找可利用的魔术方法和对象属性 构造调用链实现恶意操作 6. PHAR反序列化(PHP特有) 利用PHP的 phar:// 协议处理 .phar 文件时的反序列化操作: 构造恶意.phar文件 通过文件上传等方式将其传至服务器 使用 phar:// 协议触发反序列化 漏洞检测方法 Java : 查找以 rO0 开头的Base64数据 使用URLDNS或JRMPClient链检测 PHP : 查找明显的序列化字符串格式 搜索 unserialize() 函数调用 通用方法 : 修改序列化数据观察应用程序行为 监控异常网络请求(DNS/HTTP) 漏洞防御措施 避免使用反序列化 :尽可能使用其他数据交换格式 严格验证输入 :在反序列化前验证数据完整性和签名 限制反序列化类 :使用白名单限制可反序列化的类 日志与监控 :记录反序列化操作并监控异常 代码审计 :检查所有反序列化点及魔术方法 实战案例解析 案例1:Java反序列化导致SQL注入 发现备份文件泄露数据库配置 分析源码发现SQL拼接漏洞 构造包含SQL注入payload的序列化对象 通过反序列化触发注入获取管理员凭证 案例2:PHP魔术方法链实现RCE 分析源码发现 __destruct 删除文件功能 构造调用链: CustomTemplate->desc 设置为 DefaultMap 实例 DefaultMap->callback 设置为 exec 通过 __get 魔术方法调用 exec 实现任意命令执行 案例3:PHAR反序列化利用 发现文件上传功能 构造恶意.phar文件伪装为图片上传 通过 phar:// 协议触发反序列化 利用SSTI(服务器端模板注入)执行命令 总结 不安全的反序列化是Web安全中的高危漏洞,理解其原理和利用技术对安全从业者至关重要。防御需要从代码设计、输入验证和运行时保护等多层面入手。随着应用程序复杂度增加,反序列化漏洞的利用方式也在不断演变,需要持续关注最新的研究和防护技术。