SharePoint 远程代码执行漏洞安全通告

发布时间 2019-03-29

漏洞编号和级别


CVE编号:CVE-2019-0604,危险级别:高危, CVSS分值:7.8


影响版本:


Microsoft SharePoint Server 2019
Microsoft SharePoint Enterprise Server 2016
Microsoft SharePoint Foundation 2013 Service Pack 1
Microsoft SharePoint Server 2010 Service Pack 2


漏洞概述


SharePoint是微软的一款团队协作解决方案,用于团队间共享和管理内容和知识。它使用ASP.NET开发,后端数据库使用Microsoft SQL Server。
成功利用漏洞,可导致Windows系统服务器远程执行命令,有可能完全控制服务器。
攻击者可将精心构造的请求通过ItemPicker WebForm控件传入后端EntityInstanceIdEncoder.DecodeEntityInstanceId(encodedId)方法中,因为方法没有对传入的encodedId进行任何处理,也没有对XmlSerializer构造函数的类型参数进行限制,可直接通过XmlSerializer反序列化,造成命令执行。
要利用该漏洞,需要授权访问SharePoint提供的管理网页,授权账户可以是一个域账户。


漏洞细节


利用条件:


可授权访问SharePoint提供的管理网页,授权账户可以是一个域账户。


环境搭建:


•    Windows server 2016
•    ASP.NET相关组件
•    Microsoft SQL Server
•    SharePoint Server
安装SharePoint前可以先运行prerequisiteinstaller 安装SharePoint必备的组件,然后安装Microsoft SQL Server,配置好账户。如果在单机上搭建SharePoint需要在此时将服务器切换为域控服务器,然后再建立域账号安装和部署SharePoint。本地账号不符合SharePoint的部署要求。


漏洞分析:


漏洞入口在http:// SharePointDomin Or IP>:/_layouts/15/Picker.aspx?PickerDialogType=,通过修改WebForm PostBack后携带参数ctl00%24PlaceHolderDialogBodySection%24ctl05%24hiddenSpanData的值来加载Payload。使用反编译工具ILSpy加载SharePoint.dll搜索入口ItemPickerDialog,通过分析它的构造函数,发现其调用了父类的构造函数,传参如下:



进入父类PickerDialog中,看构造函数:



其中EntityEditorWithPicker也是一个WebForm控件,说明在这里传入了一个EntityEditorWithPicker的子类ItemPicker,跟入ItemPicker可看到ItemPicker确实继承自EntityEditorWithPicker,EntityEditorWithPicker又继承自EntityEditor:


 



EntityEditor实现了接口:IPostBackDataHandler和ICallbackEventHandler,根据WebForm控件的生命周期,在页面中有事件触发__doPostBack()后,先调用通过ICallbackEventHandler实现的RaiseCallbackEvent()方法和GetCallbackResult()方法得到表单内容,再调用通过IPostBackDataHandler实现的LoadPostData()方法。




回到EntityEditor中看GetCallbackResult()方法中调用了InvokeCallbackEvent()方法,InvokeCallbackEvent()方法调用了ParseSpanData()方法:





来到ParseSpanData()中可以看出这里把表单提交的数据进行了处理。此处逻辑非常复杂,我们只跟对HiddenSpanData的处理:



可发现此方法将HiddenSpanData的值放入了PickerEntity的List中,在经过一些处理后分割成数组,遍历数组,新建PickerEntity对象pickerEntity2,将其值放入pickerEntity2.Key中,最终放入arrayList中并赋值给类成员变量m_listOrderTemp:



回到LoadPostData()方法看对m_listOrderTemp成员变量的处理,可看到在这里遍历了m_listOrderTemp成员变量的值并将其加进m_listRevalidation成员变量中,然后迭代进行Validate()操作:



在Validate()方法中,将m_listOrderTemp成员变量赋值给m_listOrder成员变量:



然后遍历Entities的值调用ValidateEntity()方法:



Entities的值来自于上面的一行很不起眼的Lambda表达式方法,此方法将返回m_listOrder成员变量的值:



跟到ValidateEntity()方法发现是虚方法,因此去子类找方法的重写。



来到EntityEditorWithPicker类中看到了ValidateEntity() 方法的重写,发现其将PickerEntity的key(pe.Key)传入了Microsoft.SharePoint.BusinessData.Infrastructure.EntityInstanceIdEncoder.DecodeEntityInstanceId()中。
进入DecodeEntityInstanceId() 方法发现反序列化,并且XmlSerializer构造函数的类型参数可控。



补丁分析:


安装补丁KB4462211后再次反编译,对比DecodeEntityInstanceId()方法的源码,发现已经不再支持对象类型的反序列化。



漏洞利用


在漏洞分析时,我们在EntityInstanceIdEncoder类中看到另一个方法EncodeEntityInstanceId(),可以直接使用它生成Payload。
构造XML:



生成Payload:



生成Payload时会弹出一次计算器,关掉即可。
PoC:



修复建议


目前官方已推出相应补丁,请尽快升级进行修复。
Microsoft SharePoint Enterprise Server 2016
Security Update for Microsoft SharePoint Enterprise Server 2016(KB4462211)
https://www.microsoft.com/en-us/download/details.aspx?id=58072
Microsoft SharePoint Foundation 2013 Service Pack 1
Security Update for Microsoft SharePoint Enterprise Server 2013(KB4462202)
https://www.microsoft.com/en-us/download/details.aspx?id=58063
Microsoft SharePoint Server 2010 Service Pack 2
Security Update for 2010 Microsoft Business Productivity Servers(KB4462184)
https://www.microsoft.com/en-us/download/details.aspx?id=58066
Microsoft SharePoint Server 2019
Security Update for Microsoft SharePoint Server 2019 Core(KB4462199)
https://www.microsoft.com/en-us/download/details.aspx?id=58061


参考链接


https://www.thezdi.com/blog/2019/3/13/cve-2019-0604-details-of-a-microsoft-sharepoint-rce-vulnerability
https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/CVE-2019-0604