Hello there, ('ω')ノ
ねらい
このLABは、すでに分かっているcarlos:montoyaのユーザー名とパスワードでログイン後、2要素目の4桁ワンタイムコードを総当たり(0000–9999)で破り、My accountに到達するのが目的です。
ただし、間違いを2回入力するとログアウトされる仕様があるため、BurpのSession Handling Rule(マクロ)で「毎リクエスト送信前に自動ログイン」させ、Intruderの各試行に最新のセッション/CSRFを注入し続けるのが鍵です。
さらに、コードは一定間隔で更新されるため、うまく当たるまで何度かアタックを回す必要があります。
全体像(まずは流れ)
- ブラウザで通常ログイン → 2FA入力画面の挙動(2回ミスでログアウト)を確認
- Burpで/login → /login(POST) → /login2(GET)の3リクエストをマクロ化
- セッションルールで「すべての送信前にこのマクロを走らせる」「マクロ応答からCSRF等を抽出して置換」を設定
- /login2(POST)をIntruderに送り、mfa-codeだけをペイロードにして0000–9999を送出(同時接続1)
- ステータス302などの「当たり」応答を見つけてブラウザで開く → My accountに到達してクリア
実践:一手ずつ「なぜそうするか」を添えて
1) 挙動確認(2回ミスで追い出される理由を把握)
- 操作:ブラウザでcarlos / montoyaでログイン → 2FA画面で適当な4桁を2回入れてみる。
- 観察:ログイン画面へ戻される。
- なぜ:以後の総当たりでは連続ミスが避けられないため、各試行の直前に自動ログイン→2FA画面へ遷移し直す必要がある=マクロの出番です。
2) Burpでマクロを作る(自動ログインの土台)
- Burp右上のSettings → Sessions → Session Handling Rules → Add。
- Scopeタブ → Include all URLs を選択(簡便のため全URLに適用)。
- Detailsタブ → Rule Actions の Add → Run a macro。
Select macro の Add でMacro Recorderを開き、以下の3リクエストを順に選択:
- GET /login(ログインフォーム取得:CSRF取得に使う)
- POST /login(username=carlos&password=montoya&csrf=… を含む本ログイン)
- GET /login2(2FAコード入力フォーム取得:最新CSRFやセッション確立の確認に使う)
- Macro EditorでTest macro → 最後の応答が「4桁コード入力ページ」になっていることを確認(=成功)。
- そのままOKで閉じる。
ポイント:
- 送信前マクロが毎回新しいCSRFとセッションを用意してくれる。2回ミスで追い出される問題を根本的に回避。
- Cookie jarを使う設定をON(デフォルトでONのことが多い)。これでログイン後クッキーが次リクエストに反映される。
3) リクエストの「置換」設定(CSRFの自動注入)
Session handling ruleのRun a macroアクション内にある以下のオプションを確認します:
- Use cookies from the session handling cookie jar:チェック(ログイン後クッキーを適用)。
- Update the request with the following parameters extracted from the macro:Addを押し、抽出元にGET /login2(または必要に応じて/ login)を指定し、応答HTMLから<input name="csrf" value="...">のvalueを抽出するルールを作成(自動正規表現や「input名で抽出」機能を使う)。
これで、Intruderが送るPOST /login2のcsrfパラメータが、毎回直前マクロで得た最新値に差し替えられます。
4) /login2(POST)をIntruderへ送る(総当たりの本体)
- 2FA画面で送られているPOST /login2をProxyから右クリック → Send to Intruder。
- Positionsで、mfa-codeのみを§…§で囲む(他は固定)。アタックタイプはSniperでOK(1パラメータのみ)。
Payloads → Numbers を選択。
- Range: 0 〜 9999
- Step: 1
- Min/Max integer digits: 4(ゼロ埋め 0000〜)
- Max fraction digits: 0
Resource pool(右側サイドパネル)でこの攻撃を新規プールへ追加し、Maximum concurrent requests = 1に設定。
- なぜ:同時並行だとセッションが競合し、マクロによる「ログイン→2FA到達→送信」の順序が崩れて失敗しやすいから。
- (任意)Follow redirectionsはオフにしておくと、302で当たりを一目で判別できます。
5) 攻撃を開始し、「当たり」を開く
- 操作:Start attack。
- 観察:多くは200や同一レスポンスサイズだが、いつか302(または顕著にサイズが異なる応答)が現れる。
- 次の手順:そのリクエストを右クリック → Show response in browser → URLをコピー → ブラウザで開く → My accountに移動してSolved。
注意:コードは定期的に更新されます。走査中に更新されると、当たりを見逃すことがあります。うまくいかなければ、アタックを再開してください(問題文にもその旨の但し書きあり)。
つまずきポイント&対処
常に失敗(200/同サイズ)で当たりが出ない
- マクロのTestで、最終応答が確かに2FA画面になっているか確認。
- Cookie jarの使用とCSRF抽出→置換が有効か見直す。
- Resource poolの同時接続=1を厳守。
CSRFが古い/欠落で弾かれる
- Session handling ruleのRun a macro内で“Update the request with parameters extracted from macro”を設定したか? 抽出先はGET /login2の応答(最新CSRFが含まれる)にする。
OTP更新に負ける
- 1〜2回分の走査では当たらないことがある。攻撃を繰り返す。
- 可能なら送信速度を一定に保ち、リダイレクト検知(302)で早めに気づく。
Turbo Intruderを使う場合の考え方(任意)
Burp付属のTurbo Intruderなら、スクリプトで「毎回ログイン→2FAへ→POSTでコード送信」を1本のパイプに載せられます。概念的には下記の流れです。
- GET /loginでCSRF取得
- POST /loginでログイン(Cookie更新)
- GET /login2で2FA用CSRF取得
- POST /login2(mfa-code=0000〜9999)を順送、302で検知して停止
スクリプト詳細は環境差があるため省略しますが、要は各ステップで最新Cookie/CSRFを継承しながらPOSTを回す点が本質です。
実務目線の学び(防御の勘どころ)
- 2FAコードのレート制限:IP/アカウント単位で試行回数と間隔を制御。
- アカウントロック:一定回数失敗で長めのクールダウン、またはサポート経由解除に。
- コード桁数と寿命:4桁は小さすぎ。6桁以上+短寿命+ドリフト考慮が無難。
- CSRF/セッションの厳格化:応答とPOSTの1:1紐づけやワンタイムトークン化で自動化を阻害。
- ログ監視:連番コード試行の時系列パターン検知。
まとめ(思考パターンの定着)
本LABの肝は、「2回ミスでログアウト」という仕様を、Burpのマクロ+セッションハンドリングで上書きし、各試行の直前に必ず新規ログイン→2FA画面到達→最新CSRFで送信という安定した手順を作ること。 その上で、IntruderのNumbers(0000–9999)、同時接続1、302検知という3点を守れば、コードの更新にぶつかっても繰り返しで最終的に当たります。 この「自動ログインで状態を整える → 総当たりは最小並列で安定化 → 異常系(302/サイズ差)で当たり検知」という型は、2FA周りのブートフォースに非常に再現性が高いアプローチです。
Best regards, (^^ゞ