原文鏈接:Phan tích CVE-2023-29357 – Microsoft SharePoint ValidateTokenIssuer Authentication Bypass Vulnerability
譯者:知道創宇404實驗室翻譯組
CVE 簡要說明
CVE-2023-29357它允許攻擊者繞過身份驗證并升級權限,是一個影響SharePoint使用的漏洞。由于未正確驗證 JWT 令牌的簽名,該漏洞存在于 ValidateTokenIssuer 方法內部。
受影響的版本為:小于16.0.10399.20005。
相關公告:
- https://msrc.microsoft.com/update-guide/vulnerability/CVE-2023-29357
- https://www.zerodayinitiative.com/advisories/ZDI-23-882/
解決辦法
- 升級到最新版本的SharePoint。
- 啟用AMSI集成功能并使用Windows Defender。
具體分析
在SPJsonWebSecurityBaseTokenHandler類中添加MissingAlgorithm枚舉,以覆蓋傳入的令牌缺少算法的情況。

重寫ReadToken方法,并調用SPAuthenticationAlgorithmValidator.ValidateAlgorithm。

ValidateAlgorithm繼續調用HasValidAlgorithm方法來檢查JWT中的alg的值。

ZDI的公告中也描述了該漏洞存在于ValidateTokenIssuer方法中。補丁代碼添加了調用SPClaimsUtility.IsEnableOldHashedProofTokenFormat方法的代碼段。


調用堆棧到ValidateTokenIssuer:

基于以上信息,可以用該算法制作 JWT 令牌并執行與 JWT 發行者( JWT 令牌 none 值)相關的操作。
為了進行身份驗證,SharePoint會從以下兩個位置獲取令牌: GET param prooftoken/headerX-PROOF_TOKEN和 header Authorization。

該令牌需要具有以下值:

-
ver: giá tr? ph?i làhashedprooftoken. -
nbf和exp: JWT 令牌的當前時間值和過期時間 -
aud和iss: 是目標受眾和發行者的值,這里必須是00000003-0000-0ff1-ce00-000000000000。該值00000003-0000-0ff1-ce00-000000000000代表Office 365 SharePoint Online的應用程序ID,其也可以在本地部署的SharePoint版本中使用。

realm: 這個值通過向API發送Authorization中的令牌值的請求,其會泄露該值。

在嘗試使用上述格式發送JWT后,SharePoint識別出當前用戶是“SharePoint App”。


雖然用戶已經成功認證SharePoint App,但該漏洞的目的是我們需要冒充farmadmin賬戶。使用/_api/web/siteusers端點列出當前站點上具有權限的用戶。

為了模擬其他賬戶,我們需要修改proof token中的nameid字段.此時,我們的proof token如下所示:

在使用新令牌進行請求后,進程報錯Specified method is not supported。

進行調試找出原因,異常在SPApplicationPrincipalName.CreateFromString方法中顯現。

主要原因是我們當前的值applicationPrincipleName沒有@字符,因此無法拆分成長度為2的數組。

SPApplicationPrincipalName.CreateFromString方法從堆棧跟蹤向上追溯一點,SharePoint會檢查SPAppRequestContext.Current是否有效,如果有效,則調用SPAppRequestContext.Current.ClientId ? SPApplicationPrincipalName.CreateFromString,如上面的堆棧跟蹤截圖所示。

因此,只需要將SPAppRequestContext.Current的值設置為null,就不會再調用ClientId了。
經過一段時間的調試,我發現SPAppRequestContext.InitCurrent方法負責給SPAppRequestContext.Current賦值。其中調用了SPApplicationRequestHelper.IsApplicationRequest方法來檢查發送的請求是否是“應用程序請求”。

該方法如下:

在這里,我們只需要關注spincomingOAuthIdentityType兩個常量SPIncomingOAuthIdentityType.UserAndApplication和SPIncomingOAuthIdentityType.ApplicationOnly進行比較。只要我們的請求不符合這兩個條件,SPAppRequestContext.Current就是null。
為了使spincomingOAuthIdentityType不等于上述兩個值,我們需要關注SPIncomingTokenContext.SetIdentityType方法。該方法通過我們發送的proof token來確定我們的token是用戶還是應用程序。

經過一段時間的調試,我們發現當我的proof token中的isuser字段的值為true時,可以將claimsIdentity.Actor的值設置為null,從而不進入if語句的內部代碼塊。

然后,程序繼續執行到下面的SPIncomingTokenContext.IsProofToken方法,該方法檢查proof token中的tt字段,如果該字段不存在,則跳過并返回false。

因此,我們成功將IdentityType設置為UserOnly而不是UserAndApplication或ApplicationOnly。

此時,SPApplicationRequestHelper.IsApplicationRequest的返回值為false,app請求上下文設置為null。


至此認證已經成功。

目前的proof token是:

在使用新的令牌重新嘗試后,結果如下:

成功模擬farmadmin賬戶后,我們可以繼續利用CVE-2023-24955來RCE,這個漏洞我會在下一篇博文中寫到。
本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/3021/
暫無評論