.NET高级代码审计(第八课)SoapFormatter反序列化漏洞
字数 1606 2025-08-18 11:38:28

.NET SoapFormatter反序列化漏洞深度分析与防御指南

一、SoapFormatter概述

SoapFormatter是.NET框架中用于序列化和反序列化对象为SOAP格式的类,实现了IFormatter接口。它可以将.NET对象转换为SOAP格式的XML数据,也可以将SOAP数据反序列化为.NET对象。

核心特性

  • 实现了IFormatterIRemotingFormatter接口
  • 使用SOAP(Simple Object Access Protocol)格式进行序列化
  • 包含CLR类型信息,支持类型精确性
  • 从.NET Framework 2.0开始逐渐被BinaryFormatter替代

二、SoapFormatter序列化机制

基本序列化示例

[Serializable]
public class TestClass
{
    public string classname;
    public string name;
    public int age;
    
    public static void ClassMethod()
    {
        Process.Start("calc.exe");
    }
}

// 序列化代码
TestClass test = new TestClass();
test.classname = "360";
test.name = "Ivan1ee";
test.age = 18;

SoapFormatter formatter = new SoapFormatter();
using (FileStream fs = new FileStream("data.xml", FileMode.Create))
{
    formatter.Serialize(fs, test);
}

序列化输出示例

生成的SOAP-XML包含完整的程序集信息:

<SOAP-ENV:Envelope 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" 
    xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" 
    xmlns:clr="http://schemas.microsoft.com/soap/encoding/clr/1.0" 
    SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
    <SOAP-ENV:Body>
        <a1:TestClass id="ref-1" xmlns:a1="http://schemas.microsoft.com/clr/nsassem/WpfApp1/WpfApp1%2C%20Version%3D1.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3Dnull">
            <classname id="ref-3">360</classname>
            <name id="ref-4">Ivan1ee</name>
            <age>18</age>
        </a1:TestClass>
    </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

三、SoapFormatter反序列化漏洞

基本反序列化流程

SoapFormatter formatter = new SoapFormatter();
using (FileStream fs = new FileStream("data.xml", FileMode.Open))
{
    TestClass obj = (TestClass)formatter.Deserialize(fs);
    Console.WriteLine(obj.name); // 输出: Ivan1ee
}

漏洞原理

当SoapFormatter反序列化不受信任的SOAP数据时,攻击者可以构造恶意SOAP-XML,利用.NET类型系统中的特定类型实现远程代码执行(RCE)。

四、攻击向量分析

1. ActivitySurrogateSelector攻击向量

这是SoapFormatter反序列化中最危险的攻击向量之一,利用工作流组件中的代理选择器实现代码执行。

攻击原理

  1. 利用System.Workflow.ComponentModel.Serialization.ActivitySurrogateSelector
  2. 通过实现ISerializationSurrogate接口控制序列化过程
  3. 结合ISerializable接口完全控制序列化数据

关键代码结构

public class PayloadClass : ISerializable
{
    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        List<byte[]> list = new List<byte[]>();
        list.Add(new PocClass());
        
        IEnumerable map_type = typeof(Type).Assembly.GetTypes();
        var e3 = Activator.CreateInstance(map_type.GetType(), list);
        
        // 填充分页控件数据源
        PageDataSource pageDataSource = new PageDataSource();
        pageDataSource.DataSource = e3;
        
        // 配合填充MenuCommand类properties属性
        DesignerVerb verb = new DesignerVerb("test", null);
        MenuCommand command = new MenuCommand(null, verb);
        
        // 使用DataSet和DataTable对象
        DataSet dataSet = new DataSet();
        dataSet.RemotingFormat = SerializationFormat.Binary;
        dataSet.CaseSensitive = false;
        
        // 使用BinaryFormatter序列化
        BinaryFormatter binaryFormatter = new BinaryFormatter();
        binaryFormatter.SurrogateSelector = new MySurrogateSelector();
        // 序列化操作...
    }
}

2. PSObject攻击向量 (CVE-2017-8565)

利用Windows PowerShell远程处理中的漏洞,通过System.Management.Automation.PSObject类型实现代码执行。

注意:此漏洞已在微软补丁中修复,打了补丁的系统无法利用。

五、漏洞利用场景分析

1. 直接XML载入

public void VulnerableMethod(string source)
{
    SoapFormatter formatter = new SoapFormatter();
    using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(source)))
    {
        formatter.Deserialize(ms); // 危险操作
    }
}

攻击者只需控制传入的source参数,提供恶意构造的SOAP-XML即可实现攻击。

2. 文件读取场景

public object DeserializeSOAP(string path)
{
    SoapFormatter formatter = new SoapFormatter();
    using (FileStream fs = new FileStream(path, FileMode.Open))
    {
        return formatter.Deserialize(fs); // 危险操作
    }
}

如果path参数可控,攻击者可以指定包含恶意SOAP-XML的文件路径。

六、防御措施

1. 最佳实践

  1. 避免使用SoapFormatter:从.NET Framework 2.0开始,官方建议使用BinaryFormatter替代SoapFormatter
  2. 使用安全序列化器:考虑使用DataContractSerializer或Json.NET等更安全的序列化器

2. 代码层面防御

// 安全反序列化模式
public object SafeDeserialize(byte[] data)
{
    // 创建受限的SerializationBinder
    var binder = new RestrictedSerializationBinder();
    
    SoapFormatter formatter = new SoapFormatter();
    formatter.Binder = binder;
    
    using (MemoryStream ms = new MemoryStream(data))
    {
        // 添加额外的验证逻辑
        if (!IsSafeData(ms))
        {
            throw new SecurityException("Unsafe data detected");
        }
        
        return formatter.Deserialize(ms);
    }
}

// 自定义受限的SerializationBinder
public sealed class RestrictedSerializationBinder : SerializationBinder
{
    public override Type BindToType(string assemblyName, string typeName)
    {
        // 只允许反序列化安全的类型
        if (typeName == typeof(SafeClass).FullName)
        {
            return typeof(SafeClass);
        }
        
        throw new SerializationException($"Type {typeName} is not allowed");
    }
}

3. 配置层面防御

  1. 实施代码访问安全策略(CAS)
  2. 使用.NET Framework的最新安全更新
  3. 在反序列化前验证输入数据的签名或哈希

七、代码审计要点

  1. 查找SoapFormatter使用:全局搜索SoapFormatter类的使用
  2. 检查输入源:确认反序列化的数据来源是否可控
    • 文件读取路径
    • 网络传输数据
    • 用户输入数据
  3. 验证类型限制:检查是否实现了SerializationBinder限制反序列化类型
  4. 检查SurrogateSelector:确认是否使用了自定义的安全代理选择器

八、总结

SoapFormatter反序列化漏洞是.NET应用程序中严重的安全威胁,攻击者可以通过精心构造的SOAP-XML实现远程代码执行。开发人员应当:

  1. 尽量避免使用SoapFormatter
  2. 如果必须使用,实施严格的类型限制
  3. 对所有反序列化操作进行输入验证
  4. 保持.NET Framework和所有安全补丁更新

随着.NET的发展,更安全的序列化方案不断出现,开发人员应当及时评估和迁移到更安全的替代方案。

.NET SoapFormatter反序列化漏洞深度分析与防御指南 一、SoapFormatter概述 SoapFormatter是.NET框架中用于序列化和反序列化对象为SOAP格式的类,实现了IFormatter接口。它可以将.NET对象转换为SOAP格式的XML数据,也可以将SOAP数据反序列化为.NET对象。 核心特性 实现了 IFormatter 和 IRemotingFormatter 接口 使用SOAP(Simple Object Access Protocol)格式进行序列化 包含CLR类型信息,支持类型精确性 从.NET Framework 2.0开始逐渐被BinaryFormatter替代 二、SoapFormatter序列化机制 基本序列化示例 序列化输出示例 生成的SOAP-XML包含完整的程序集信息: 三、SoapFormatter反序列化漏洞 基本反序列化流程 漏洞原理 当SoapFormatter反序列化不受信任的SOAP数据时,攻击者可以构造恶意SOAP-XML,利用.NET类型系统中的特定类型实现远程代码执行(RCE)。 四、攻击向量分析 1. ActivitySurrogateSelector攻击向量 这是SoapFormatter反序列化中最危险的攻击向量之一,利用工作流组件中的代理选择器实现代码执行。 攻击原理 利用 System.Workflow.ComponentModel.Serialization.ActivitySurrogateSelector 类 通过实现 ISerializationSurrogate 接口控制序列化过程 结合 ISerializable 接口完全控制序列化数据 关键代码结构 2. PSObject攻击向量 (CVE-2017-8565) 利用Windows PowerShell远程处理中的漏洞,通过 System.Management.Automation.PSObject 类型实现代码执行。 注意:此漏洞已在微软补丁中修复,打了补丁的系统无法利用。 五、漏洞利用场景分析 1. 直接XML载入 攻击者只需控制传入的 source 参数,提供恶意构造的SOAP-XML即可实现攻击。 2. 文件读取场景 如果 path 参数可控,攻击者可以指定包含恶意SOAP-XML的文件路径。 六、防御措施 1. 最佳实践 避免使用SoapFormatter :从.NET Framework 2.0开始,官方建议使用BinaryFormatter替代SoapFormatter 使用安全序列化器 :考虑使用DataContractSerializer或Json.NET等更安全的序列化器 2. 代码层面防御 3. 配置层面防御 实施代码访问安全策略(CAS) 使用.NET Framework的最新安全更新 在反序列化前验证输入数据的签名或哈希 七、代码审计要点 查找SoapFormatter使用 :全局搜索 SoapFormatter 类的使用 检查输入源 :确认反序列化的数据来源是否可控 文件读取路径 网络传输数据 用户输入数据 验证类型限制 :检查是否实现了 SerializationBinder 限制反序列化类型 检查SurrogateSelector :确认是否使用了自定义的安全代理选择器 八、总结 SoapFormatter反序列化漏洞是.NET应用程序中严重的安全威胁,攻击者可以通过精心构造的SOAP-XML实现远程代码执行。开发人员应当: 尽量避免使用SoapFormatter 如果必须使用,实施严格的类型限制 对所有反序列化操作进行输入验证 保持.NET Framework和所有安全补丁更新 随着.NET的发展,更安全的序列化方案不断出现,开发人员应当及时评估和迁移到更安全的替代方案。