Hello there, ('ω')ノ
ねらい
このLABは、アカウントロック機能の実装ミスを突いて、有効なユーザー名を推測し、そのユーザーのパスワードを総当たりで特定することが目的です。 通常、アカウントロックは総当たり攻撃を防ぐ仕組みですが、ロック時のエラーメッセージや応答挙動が微妙に異なる場合、それが有効なユーザー名を見抜くヒントになります。
全体像(まずはストーリー)
- ログインフォームで意図的に間違ったユーザー名+パスワードを試す。
- 有効なユーザー名を探すため、複数回連続で試し、ロック時の挙動の違いを観察する。
- 違いが出たユーザー名を特定。
- そのユーザー名に対し、パスワードリストで総当たり攻撃を仕掛ける。
- 正しい組み合わせを発見し、ログインしてアカウントページにアクセスする。
実践:一手ずつ「なぜそうするか」を添えて
1) ログインページを確認
- 操作:ブラウザでLABを開き、ログインフォームの構造をチェック。
- なぜ:送信時のHTTPリクエスト構造(POST /login など)を把握し、後でBurp Intruderで自動化するため。
2) 適当なユーザー名とパスワードを送信
操作:
- ユーザー名:
invalid-username - パスワード:
invalid-password - Burpでリクエストをキャプチャ。
- ユーザー名:
- なぜ:まずは標準的な失敗時の応答を知るため。これが基準になります。
3) Burp Intruderで「Cluster bomb」モードを選択
操作:
- username=§invalid-username§&password=example**§§**
- 1つ目の§でユーザー名を変化させる。
- 2つ目はパスワード欄の末尾に空ペイロードを追加し、同じユーザー名を複数回試せるようにする。
- なぜ:ユーザー名ごとに5回ずつ試すことで、ロック判定まで持っていき、エラー文の違いを検出しやすくするため。
4) ペイロードを設定
操作:
- ペイロードセット1:LABの候補ユーザー名リスト。
- ペイロードセット2:Nullペイロード(5回繰り返し)。
- なぜ:同じユーザー名を複数回試せば、もしそれが有効なら**「ロックされた」旨のメッセージ**が返る可能性がある。
5) 結果を分析
- 観察:ほとんどは同じエラー(例:
Invalid username or password)。 しかし1つのユーザー名だけはレスポンスの長さや本文が微妙に異なる(例:You have made too many incorrect login attempts)。 - なぜ:これはそのユーザー名が有効であり、連続失敗によりロック状態になった証拠。
6) パスワード総当たり(Sniperモード)
操作:
- 固定したユーザー名(先ほど特定したもの)を設定。
- パスワード欄に§をつけて候補パスワードリストを設定。
- 「Grep Extract」でエラー文部分を抽出。
- なぜ:エラー文が消える=ログイン成功と判断できるため、レスポンスを1つずつ目視しなくても正解を見つけられる。
7) 正しいパスワードの発見
- 観察:ほとんどはエラー文あり。1つだけ空欄(または異なる文言)がある。
- なぜ:そのレスポンスがログイン成功時の画面。
8) ロック解除を待つ
- 操作:1分程度待機してから、正しいユーザー名+パスワードでログイン。
- なぜ:直前まで何度も失敗しているため、ロック解除を待たないと成功しても入れない。
9) アカウントページへアクセスしてクリア
- 操作:ログイン後、アカウントページを開くとLABクリア。
どうして成立するのか(思考の軸)
- アカウントロック時のエラー文が他と違う → 攻撃者に「このユーザーは存在する」という情報を漏らしてしまう。
- 有効ユーザーのみにロックが発生 → ロックは「認証の前段階」ではなく「パスワード認証の後」に動くため、存在しないユーザーはロックされない。
つまずきポイント&対処
- 全員同じエラー文に見える → レスポンス長やHTML微差(タグやスペース)で判別。
- ロック解除が遅い → 再試行間隔を伸ばすか、LAB説明文のヒントを確認。
- Grep Extractが反応しない → ターゲット文字列の選び方を見直す(完全一致より部分一致が安定)。
実務目線の防御策
- エラーメッセージを統一:存在するか否かを区別できない文章にする。
- アカウントロック判定をユーザー名レベルでなくIPレベルでも適用:総当たり速度を落とす。
- レート制限やCAPTCHAの導入:自動化を難しくする。
Best regards, (^^ゞ