CVE-2019-0604:微软SHAREPOINT远程执行的脆弱性分析
Pinging 漏洞分析 8864浏览 · 2019-03-22 01:15

上个月,Microsoft发布了补丁来解决SharePoint中的两个远程代码执行(RCE)漏洞。使用这两个被评级为严重的漏洞,攻击者可以发送任意命令请求并在SharePoint应用和服务器账户中执行任意代码。 Markus WulftangeZDI计划报告了这两个漏洞。 他提供了有关CVE-2019-0604细节。

在搜索新漏洞时,一种有效方法是自下而上进行搜索。文章描述到,在分析寻找控制流数据流的过程中我们可以使用一种比较新颖的方法以便能够查明数据能否接触到sink

其中一个常用的sink是使用XmlSerializer反序列化方法。 通常,它被认为是一个安全的序列化程序,因为它必须使用指定的类型数据进行检测,并且不能出现在期望类型的对象图中。但是,如果预期的类型数据也可以被控制,那么它也是可以被利用的,因为在星期五的时候,它已经由AlvaroMuñozOleksandr Mirosh在其第13次JSON攻击中记录下来PDF

为了分析SharePoint 2016程序集,dnSpy是一个很好的工具,因为它可以用于.NET应用程序的反编译和调试。因此,在将dnSpy附加到运行SharePoint 2016IIS工作进程w3wp.exe并且加载程序集之后,我们可以分析XmlSerializer(Type)构造函数的用法。现在,更为复杂的分析部分是我们必须看每个XmlSerializer(Type)构造函数的调用并检查其类型是否完全可变。例如它不像新XmlSerializer中那样使用硬编码的方法。

调用XmlSerializer(Type)构造函数的方法之一是Microsoft.SharePoint.dll中的Microsoft.SharePoint.BusinessData.Infrastructure.EntityInstanceIdEncoder.DecodeEntityInstanceId(string)方法。具有相同功能的类型也位于Microsoft.SharePoint.Portal.dll中的Microsoft.Office.Server.ApplicationRegistry.Infrastructure命名空间中。稍后我们将回到此处并使用Microsoft.SharePoint.dll中的方法进行下一步操作。

这里,用于指定期望类型的typeName和反序列化的数据都源自文本函数,该文本源自方法的参数encodedId

只要调用该方法并对传递的参数进行控制,那么就能够完美运行我们的程序。

追溯数据流源头

下一步是通过调用函数并查看它们是否来自可以从外部进行启动以及是否也可以提供参数值。

如果用户熟悉ASP.NET,则某些方法并不陌生,如Page_Load(object,EventArgs)OnLoad(EventArgs)。 它们在ASP.NET生命周期中被调用,它们在扩展System.Web.UI.Page中定义的类型表示.aspx文件的基类型。 事实上,这三种类型都有相应的.aspx文件:

· Microsoft.SharePoint.ApplicationPages.ActionRedirectPage:
/_layouts/15/ActionRedirect.aspx

· Microsoft.SharePoint.ApplicationPages.DownloadExternalData:
 /_layouts/15/downloadexternaldata.aspx

 · Microsoft.SharePoint.Portal.WebControls.ProfileRedirect:
 /_layouts/15/TenantProfileAdmin/profileredirect.aspx

虽然在这三种情况下,参数值都来自HTTP请求,但它们同样是URL的查询字符串。 这可能会出现一个问题,因为十六进制编码会将长度乘以4,从而可以变得非常长并超过HTTP请求行的限制。

经过进一步分析,最后一个,ItemPicker.ValidateEntity(PickerEntity)方法证明是一个更好的选择。

这里,传递的PickerEntityPickerEntityKey属性用于EntityInstanceIdEncoder.DecodeEntityInstanceId(string)调用。 它由EntityEditor.Validate()调用,它迭代存储在EntityEditor.Entities属性中的每个条目中以用来进行验证。

该方法由EntityEditor.LoadPostData(string,NameValueCollection)调用,该实现System.Web.UI.IPostBackDataHandler.LoadPostData(string,NameValueCollection)方法。

因此,对PostPicker Web控件的消息请求会自动调用该方法。 调用图如下所示:

并且我们要注意类型层次结构:

数据流验证

现在有一种方法可以从ItemPicker Web控件发送到达EntityInstanceIdEncoder.DecodeEntityInstanceId(string),然而此时我们仍然不清楚是否可以控制PickerEntityKey属性。

EntityEditor.Entities属性由私有字段m_listOrder决定,该字段仅在两个点处分配:在实例化期间和在EntityEditor.Validate()方法中。在后一种情况下,它获得分配的私有字段m_listOrderTemp的值。同样,该字段也只在两个点中进行分配:在实例化期间和EntityEditor.ParseSpanData方法中。该方法也由EntityEditor.LoadPostData(string,NameValueCollection)调用,其值为HtmlInputHidden,名称为“hiddenSpanData”。该字段的值可以由用户控制。

之后我们需要查看EntityEditor.ParseSpanData(string)对传递的数据所做的工作,以及它是否最终成为PickerEntityKey。我们将跳过它,因为EntityEditor.ParseSpanData(string)很长,除非它包含嵌套的

标签的特殊结构并且被解析出来,其他的内容都会在PickerEntity的Key中结束,然后出现在m_listOrderTemp列表中。

所以,现在我们现在遍历了一个向量,并允许我们从ItemPickerpost back处理到达EntityInstanceIdEncoder.DecodeEntityInstanceId(string),同时还可以控制输入。还剩下的是找到该Web控件的实例。

寻找攻击点

ItemPicker Web控件实际上从不直接在.aspx页面中使用。 但是当查看其基类型EntityEditorWithPicker时,我们发现在/_layouts/15/Picker.aspx中有一个使用它的Picker.aspx文件。

该页面要求使用对话框的类型并通过“PickerDialogType”URL参数以其程序集限定名称的形式。 在这里,可以使用以下两种ItemPickerDialog类型中的任何一种:

· Microsoft.SharePoint.WebControls.ItemPickerDialog in Microsoft.SharePoint.dll

· Microsoft.SharePoint.Portal.WebControls.ItemPickerDialog in Microsoft.SharePoint.Portal.dll

使用第一个ItemPickerDialog类型显示以下页面:

这里,底部文本字段与ItemPicker相关联。 并且还有HtmlInputHidden的通讯员,名字为ctl00 $ PlaceHolderDialogBodySection $ ctl05 $ hiddenSpanData。 这是我们的EntityInstanceIdEncoder.DecodeEntityInstanceId(string)sink的数据源。

概念证明

当使用以“”开头的ctl00 $ PlaceHolderDialogBodySection $ ctl05 $ hiddenSpanData值(如“dummy”)提交表单时,EntityInstanceIdEncoder.DecodeEntityInstanceId中的断点将显示以下情况。

此时调用堆栈如下所示:

当使用其他ItemPickerDialog类型时,只有两个最顶层的条目是不同的,如下所示:

这是ctl00 $ PlaceHolderDialogBodySection $ ctl05 $ hiddenSpanData的数据最终在EntityInstanceIdEncoder.DecodeEntityInstanceId中的证明过程。 其余的只是处理实体实例id编码并找到适当的XmlSerializerpayload。

本文为翻译文章,来自:https://www.zerodayinitiative.com/blog/2019/3/13/cve-2019-0604-details-of-a-microsoft-sharepoint-rce-vulnerability
1 条评论
某人
表情
可输入 255