与序列化有关的漏洞大全

序列化漏洞是一类因反序列化不可信数据导致的高危漏洞,广泛存在于 PHP、Java、Python 等主流语言中,常被用于远程代码执行 (RCE)、文件读写等攻击。以下是按语言分类的常见序列化漏洞:

一、PHP 序列化漏洞

1. 普通反序列化漏洞

  • 原理:程序直接反序列化用户可控的字符串,触发类中的魔术方法执行恶意操作
  • 常见可利用魔术方法
  • __wakeup():反序列化时自动调用
  • __destruct():对象销毁时自动调用
  • __toString():对象被当作字符串时自动调用
  • __call():调用不存在的方法时自动调用
  • 利用条件
  • 存在用户可控的反序列化入口
  • 程序中定义了包含可利用魔术方法的类
  • 典型场景:用户信息存储在数据库的序列化字段中,读取后直接反序列化

2. Phar 反序列化漏洞

  • 原理:PHP 的文件操作函数(如file_exists()stat()file_get_contents())在解析 Phar 文件时会自动反序列化其元数据
  • 利用条件
  • 存在文件操作函数,且文件名参数用户可控
  • 可以上传或构造恶意 Phar 文件
  • PHP 配置中phar.readonly=Off(或通过zip://等协议绕过)
  • 利用方法
  1. 构造包含恶意序列化数据的 Phar 文件
  2. 将 Phar 文件上传到服务器(或通过其他方式让服务器可访问)
  3. 利用文件操作函数触发 Phar 反序列化
  • 优势:不需要直接的unserialize()调用,通过文件操作即可触发

二、Java 序列化漏洞

1. Apache Commons Collections 漏洞

  • 原理:Apache Commons Collections 库中的InvokerTransformerChainedTransformer等类可以通过反射调用任意方法
  • 影响版本:Commons Collections 3.1-3.2.1、4.0-4.3
  • 利用链
  • TransformedMap -> InvokerTransformer -> Runtime.getRuntime().exec()
  • LazyMap -> InvokerTransformer -> 任意代码执行
  • 典型场景:WebLogic、WebSphere、JBoss 等中间件的反序列化漏洞

2. Fastjson 反序列化漏洞

  • 原理:Fastjson 在解析 JSON 时,支持自动类型转换,攻击者可以构造恶意 JSON 触发任意代码执行
  • 影响版本:Fastjson 1.2.24-1.2.47、1.2.68 等
  • 利用方式
  • 利用@type字段指定恶意类
  • 利用AutoType机制加载危险类
  • 结合 JNDI 注入实现远程代码执行
  • 特点:利用方式多样,补丁绕过频繁,是近年来最常见的 Java 反序列化漏洞之一

3. Jackson 反序列化漏洞

  • 原理:Jackson 库在启用Polymorphic Type Handling时,攻击者可以构造恶意 JSON 触发任意代码执行
  • 影响版本:Jackson 2.x(取决于配置)
  • 利用条件
  • 启用了DefaultTyping
  • 存在可利用的恶意类(如 Spring 框架中的类)
  • 典型场景:Spring Boot 应用中使用 Jackson 处理 JSON 数据

4. RMI/JMX 反序列化漏洞

  • 原理:RMI (远程方法调用) 和 JMX (Java 管理扩展) 协议在传输过程中会使用 Java 序列化,攻击者可以发送恶意序列化数据攻击服务端
  • 利用方式
  • 攻击 RMI Registry
  • 攻击 JMX Connector
  • 结合 JNDI 注入实现远程代码执行
  • 特点:无需依赖特定库,只要目标使用了 RMI/JMX 就可能被攻击

5. JNDI 注入结合反序列化

  • 原理:攻击者通过反序列化触发 JNDI 查找,加载远程恶意类实现代码执行
  • 利用链
  • 反序列化 -> InitialContext.lookup() -> 加载远程恶意类
  • 常见于 Fastjson、Jackson、RMI 等漏洞中
  • 影响范围:Java 6u141 以下、7u131 以下、8u121 以下(高版本有默认限制)

三、Python 序列化漏洞

1. Pickle 反序列化漏洞

  • 原理:Python 的pickle模块在反序列化时会执行字节码,攻击者可以构造恶意 pickle 数据执行任意代码
  • 危险函数
  • pickle.load()
  • pickle.loads()
  • cPickle.load()
  • cPickle.loads()
  • 利用方法
  1. 定义包含__reduce__()方法的恶意类
  2. 将恶意类序列化为 pickle 数据
  3. 让目标程序反序列化该数据
  • 示例:python运行
import pickle
import os

class Evil:
    def __reduce__(self):
        return (os.system, ('whoami',))

evil_data = pickle.dumps(Evil())
pickle.loads(evil_data)  # 执行whoami命令

2. PyYAML 反序列化漏洞

  • 原理:PyYAML 在解析 YAML 时,支持构造 Python 对象,攻击者可以构造恶意 YAML 触发任意代码执行
  • 影响版本:PyYAML 5.1 以下
  • 危险函数
  • yaml.load()(不指定 Loader 时)
  • yaml.load_all()
  • 利用方法:yaml
!!python/object/apply:os.system
- whoami
  • 防御措施:使用yaml.safe_load()代替yaml.load()

3. Marshal 反序列化漏洞

  • 原理marshal模块用于序列化 Python 内部对象,反序列化恶意数据可能导致代码执行
  • 特点:比 pickle 更底层,主要用于 Python 内部,不建议用于处理不可信数据

四、其他语言序列化漏洞

1. Ruby Marshal 反序列化漏洞

  • 原理:Ruby 的Marshal.load()在反序列化时会执行代码,攻击者可以构造恶意数据触发攻击
  • 利用方法:ruby
class Evil
  def marshal_load(data)
    system("whoami")
  end
end

evil_data = Marshal.dump(Evil.new)
Marshal.load(evil_data)  # 执行whoami命令

2. Node.js 反序列化漏洞

  • 原理:Node.js 的一些第三方库(如node-serializeserialize-javascript)在反序列化时存在代码执行漏洞
  • 典型库
  • node-serialize:通过_$ND_FUNC$_前缀执行函数
  • serialize-javascript:在特定配置下存在代码执行风险
  • 示例:javascript运行
var serialize = require('node-serialize');
var evil = '{"rce":"_$ND_FUNC$_function(){require(\'child_process\').exec(\'whoami\', function(error, stdout, stderr) { console.log(stdout) });}()"}';
serialize.unserialize(evil);  // 执行whoami命令

3. .NET BinaryFormatter 反序列化漏洞

  • 原理:.NET 的BinaryFormatter在反序列化时存在代码执行漏洞,攻击者可以构造恶意数据触发攻击
  • 影响范围:使用BinaryFormatterSoapFormatterNetDataContractSerializer等序列化器的.NET 应用
  • 利用链:常见于TypeConfuseDelegateObjectDataProvider等利用链
  • 防御措施:避免使用BinaryFormatter,使用更安全的序列化器(如System.Text.Json

五、通用防御措施

  1. 避免反序列化不可信数据:这是最根本的防御措施
  2. 使用安全的序列化格式:如 JSON、XML(避免使用包含类型信息的格式)
  3. 严格校验反序列化数据:对反序列化后的对象进行类型和内容校验
  4. 限制反序列化的类:使用白名单机制,只允许反序列化特定的类
  5. 升级相关库和框架:及时修复已知的序列化漏洞
  6. 最小权限原则:运行程序的用户权限尽可能低
  7. 使用 RASP:运行时应用自我保护,检测和阻止恶意反序列化操作