旧瓶装新酒 - Microsoft SharePoint 身份验证后反序列化远程代码执行 (CVE-2022-29108)
引言
最近,我接触了一些与SharePoint相关的工作,因此正在学习如何设置和调试SharePoint的旧漏洞。二月份出现了一个反序列化漏洞CVE-2022-22005(当然是身份验证后的)。已经有一篇由越南作者撰写的详细分析博客文章(此处)。该博客写得非常热情和详细。我也依赖该博客中的细节进行设置和调试。由于本文中写的漏洞与之相关,我建议您先阅读上述文章,以便更容易理解本文!
如上所述,CVE-2022-29108与CVE-2022-22005非常密切相关。两者在操作、入口点和修补方面相似。并且很确定它是在1day分析期间发现的!
环境设置
设置完全基于MS指南此处
设置完成后,继续以下步骤:创建Web应用程序 -> 创建网站集
起初,我以为CVE-2022-22005漏洞在默认设置下有效,但在调试时发现并非如此!(不确定我的设置是否与其他人不同?)
第一个条件是“自助网站创建”功能默认禁用,这意味着具有默认配置的普通用户将无法创建子网站 ¯(ツ)/¯
ZDI博客文章中的一个示例:
因此,如果您想像这些旧文章那样工作,必须首先启用自助网站创建功能。
第二个条件是CVE-2022-22005基于SharePoint的StateService工作。此功能在默认设置下不存在。以下是StateService未启用时遇到的错误警告:
读者可以参考此文章了解如何启用此特定服务,或仅使用以下命令:
|
|
分析
让我们回顾CVE-2022-22005的接收器在ChartPreviewImage.loadChartImage():
|
|
上述sessionKey用于通过CustomSessionState.FetchBinaryData(this.sessionKey)方法从StateService获取二进制数据:
为了修补CVE-2022-22005,他们添加了一个SerializationBinder以防止任意数据反序列化:
为了找到此漏洞的变体,我专注于CustomSessionState.FetchBinaryData()方法。此方法负责从StateService检索二进制数据。 这意味着在从内存获取后必须有额外的步骤来处理此二进制数据,对吗? 使用dnSpy中的Analyze功能查找调用CustomSessionState.FetchBinaryData()的地方,结果如下:
让我们专注于ChartAdminPageBase.get_currentWorkingSet()的方法调用。此方法的内容如下:
|
|
然后从StateService检索二进制数据与此CustomSessionStateKey,然后直接传递给BinaryFormatter.Deserialize() => RCE
调用ChartAdminPageBase.get_currentWorkingSet()的调用图如下:
包括从ChartPreviewImage.Render()的方法调用(与旧漏洞CVE-2022-22005相同的入口点):
完整堆栈跟踪: ChartPreviewImage.Render()
ChartAdminPageBase.FetchFromCurrentWorkingSet() > ChartAdminPageBase.get_currentWorkingSet() > BinaryFormatter.Deserialize()
利用
利用与CVE-2022-22005完全相同,如此处所述。 然而,我仍然在本文中写下每个步骤的细节,作为未来参考的笔记!
步骤1:存储payload
首先下载并安装Microsoft InfoPath此处。 使用Infopath创建列表并发布表单如下:
使用Infopath创建列表后,我们可以访问并使用该列表创建新项目如下:
如果点击“新建”并收到以下响应,意味着StateService未在SharePoint中启用(我在本文开头提到过):
如果我们已启用StateService,将获得以下页面:
在“附件”部分上传文件,主文件内容是将用于反序列化的gadgetchain,这里我使用TypeConfuseDelegate gadget获取RCE(上传后,只需将文件留在那里,不要点击保存!):
回到burpsuite,使用上述文件上传请求,在Response部分,找到您刚刚上传的文件名。旁边将有一个形式为“hash_hash”的字符串,让我们称之为itemId,保存此值以备后续触发漏洞使用!
步骤2:获取payload会话ID
如CVE-2022-22005和CVE-2021-27076的文章所述,我们使用相同的方法存储二进制会话数据并在以后重用。 此重放方法的想法基于Infopath的文件上传处理! 当通过Infopath列表上传文件到服务器时,如步骤1 above,SharePoint将文件内容缓存到attachmentId,并将此文件的元数据(包括attachmentId)缓存到另一个itemId,然后将该itemId返回给用户。 可以通过以下图片描述:
对FormServerAttachments.aspx的请求如下:
|
|
使用从InfoPath_CanaryValue检索的sid:
|
|
并使用key参数,我使用以下代码获取它,其中_serializedKey为 步骤1中上传文件后返回的itemId:
|
|
(有关此部分的更多细节,读者可以参考CVE-2022-22005的博客文章,作者对此步骤写得非常清楚,因此我不再进一步描述!) 以下图片是FormServerAttachments.aspx请求的响应:
在响应的末尾,将包含一个形式为“hash1_hash2”的字符串,第一个哈希将与我们刚刚传入的itemId的第一个哈希匹配。 这是attachmentId,或者也是payload Id/session Key,我们将使用此attachmentId传递到ChartPreviewImage.aspx并触发反序列化:
以下是PoC的逐步演示:
如果您更喜欢阅读越南语版本,可以在此处阅读。
参考文献
- https://blog.viettelcybersecurity.com/cve-2022-22005-microsoft-sharepoint-rce/
- https://docs.microsoft.com/en-us/sharepoint/install/install-sharepoint-server-2016-on-one-server
- https://knowledge-junction.com/2022/02/26/sharepoint-2016-workflows-resolving-error-the-form-cannot-be-rendered-this-may-be-due-to-a-misconfiguration-of-the-microsoft-sharepoint-server-state-service-for-more-information-contact-your/
- https://www.microsoft.com/en-us/download/details.aspx?id=48734
- https://www.zerodayinitiative.com/blog/2021/3/17/cve-2021-27076-a-replay-style-deserialization-attack-against-sharepoint