4

CVE-2023-29357 – Microsoft SharePoint ValidateTokenIssuer 身份验证绕过漏洞分析

 1 year ago
source link: https://paper.seebug.org/3021/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

原文链接:Phân tích CVE-2023-29357 – Microsoft SharePoint ValidateTokenIssuer Authentication Bypass Vulnerability
译者:知道创宇404实验室翻译组

CVE 简要说明

CVE-2023-29357它允许攻击者绕过身份验证并升级权限,是一个影响SharePoint使用的漏洞。由于未正确验证 JWT 令牌的签名,该漏洞存在于 ValidateTokenIssuer 方法内部。

受影响的版本为:小于16.0.10399.20005。

相关公告:

  • 升级到最新版本的SharePoint。
  • 启用AMSI集成功能并使用Windows Defender。

SPJsonWebSecurityBaseTokenHandler类中添加MissingAlgorithm枚举,以覆盖传入的令牌缺少算法的情况。

img

重写ReadToken方法,并调用SPAuthenticationAlgorithmValidator.ValidateAlgorithm

img

ValidateAlgorithm继续调用HasValidAlgorithm方法来检查JWT中的alg的值。

img

ZDI的公告中也描述了该漏洞存在于ValidateTokenIssuer方法中。补丁代码添加了调用SPClaimsUtility.IsEnableOldHashedProofTokenFormat方法的代码段。

img
img

调用堆栈到ValidateTokenIssuer

img

基于以上信息,可以用该算法制作 JWT 令牌并执行与 JWT 发行者( JWT 令牌 none 值)相关的操作。

为了进行身份验证,SharePoint会从以下两个位置获取令牌: GET param prooftoken/headerX-PROOF_TOKEN和 header Authorization。

img

该令牌需要具有以下值:

img
  • ver: giá trị phải là hashedprooftoken.

  • nbfexp: JWT 令牌的当前时间值和过期时间

  • audiss: 是目标受众和发行者的值,这里必须是00000003-0000-0ff1-ce00-000000000000。该值00000003-0000-0ff1-ce00-000000000000代表Office 365 SharePoint Online的应用程序ID,其也可以在本地部署的SharePoint版本中使用。

img

图片来源:https://learn.microsoft.com/en-us/troubleshoot/azure/active-directory/verify-first-party-apps-sign-in#application-ids-of-commonly-used-microsoft-applications

  • realm: 这个值通过向API发送Authorization中的令牌值的请求,其会泄露该值。
img

在尝试使用上述格式发送JWT后,SharePoint识别出当前用户是“SharePoint App”。

img
img

虽然用户已经成功认证SharePoint App,但该漏洞的目的是我们需要冒充farmadmin账户。使用/_api/web/siteusers端点列出当前站点上具有权限的用户。

img

为了模拟其他账户,我们需要修改proof token中的nameid字段.此时,我们的proof token如下所示:

img

在使用新令牌进行请求后,进程报错Specified method is not supported

img

进行调试找出原因,异常在SPApplicationPrincipalName.CreateFromString方法中显现。

img

主要原因是我们当前的值applicationPrincipleName没有@字符,因此无法拆分成长度为2的数组。

img

根据堆栈跟踪定位到SPApplicationPrincipalName.CreateFromString方法

从堆栈跟踪向上追溯一点,SharePoint会检查SPAppRequestContext.Current是否有效,如果有效,则调用SPAppRequestContext.Current.ClientIdSPApplicationPrincipalName.CreateFromString,如上面的堆栈跟踪截图所示。

img

因此,只需要将SPAppRequestContext.Current的值设置为null,就不会再调用ClientId了。

经过一段时间的调试,我发现SPAppRequestContext.InitCurrent方法负责给SPAppRequestContext.Current赋值。其中调用了SPApplicationRequestHelper.IsApplicationRequest方法来检查发送的请求是否是“应用程序请求”。

img

该方法如下:

img

在这里,我们只需要关注spincomingOAuthIdentityType两个常量SPIncomingOAuthIdentityType.UserAndApplicationSPIncomingOAuthIdentityType.ApplicationOnly进行比较。只要我们的请求不符合这两个条件,SPAppRequestContext.Current就是null

为了使spincomingOAuthIdentityType不等于上述两个值,我们需要关注SPIncomingTokenContext.SetIdentityType方法。该方法通过我们发送的proof token来确定我们的token是用户还是应用程序。

img

经过一段时间的调试,我们发现当我的proof token中的isuser字段的值为true时,可以将claimsIdentity.Actor的值设置为null,从而不进入if语句的内部代码块。

img

然后,程序继续执行到下面的SPIncomingTokenContext.IsProofToken方法,该方法检查proof token中的tt字段,如果该字段不存在,则跳过并返回false

img

因此,我们成功将IdentityType设置为UserOnly而不是UserAndApplicationApplicationOnly

img

此时,SPApplicationRequestHelper.IsApplicationRequest的返回值为false,app请求上下文设置为null

img
img

至此认证已经成功。

img

目前的proof token是:

img

在使用新的令牌重新尝试后,结果如下:

img

成功模拟farmadmin账户后,我们可以继续利用CVE-2023-24955来RCE,这个漏洞我会在下一篇博文中写到。


Paper 本文由 Seebug Paper 发布,如需转载请注明来源。本文地址:https://paper.seebug.org/3021/


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK