Hello there, ('ω')ノ
概要(この文書で何を学べるか)
このラボでは、ログイン機能の エラーメッセージの違い から、 存在するユーザ名だけ異なる応答を返してしまう脆弱性(username enumeration) を悪用して、
- 有効なユーザ名の特定(列挙)
- そのユーザ名に対するパスワード総当たり(brute force)
- 正しい認証情報でログインしアカウントページに到達
という一連の攻撃手法を学びます。
Burp Suite の Intruder(Sniper 攻撃) を活用して、レスポンスの 長さ や メッセージ内容 の違いから正解を特定する構成になっています。
前提知識
- エラーメッセージの違い=情報漏洩 → 「Invalid username」と「Incorrect password」が異なる例が典型的。
- ブルートフォースの基本操作 → まずユーザ名の列挙、次にパスワードを試す。
- Burp Intruder(Sniper 攻撃)の仕組み → 指定したパラメータだけを一つずつ変えながら総当たりする。
なぜこの順序で進めるのか(考え方)
ユーザ名だけ先に当てるのがもっとも効率的 パスワードの総当たりは非常に時間がかかるため、まず有効なユーザ名を 1 つだけ特定するのが合理的です。
レスポンスの違いは強力な手がかり 多くのアプリは「存在しないユーザ」と「存在するがパスワードが違う場合」で 微妙に異なるレスポンス を返します。 この差異(本文の長さ・内容・ステータスコード)を Intruder が一覧表示してくれるので比較できます。
ユーザ名がわかればパスワードの特定は容易 正しい組み合わせだけ 302(リダイレクト)など、挙動が明確に変化するため判定が簡単です。
実際の手順(1 アクションごとに「なぜ」を解説)
以降の操作は必ずラボ環境でのみ行ってください。
ステップ 1 — ログインフォームに適当な値を入力し Burp で捕まえる
- ブラウザでラボのログイン画面を開く
- 適当なユーザ名(例:aaa)とパスワード(例:bbb)でログインを試す
- Burp Suite → Proxy > HTTP history に
POST /loginが記録される
なぜ? → 後で Intruder に送るため、「実際にログイン時に飛ぶリクエスト」を手に入れる必要があるからです。
ステップ 2 — Intruder に送って “ユーザ名列挙フェーズ” の準備
POST /loginを右クリック → Send to Intruder- Intruder(Positions)を開くと、
username=§invalid§のように自動的に username 部分が §で囲まれる - attack type が Sniper であることを確認
- パスワード部分は固定値のままで OK
- Payloads タブへ移動し、Payload type を Simple list にし、 candidate usernames を貼り付ける
- Start attack
なぜ? → Sniper攻撃では「1 箇所だけ変える」という操作が自動化されるため、ユーザ名だけを試すのに最適です。
ステップ 3 — Length 列の違いから 有効なユーザ名 を特定
Attack のウィンドウで結果を見る。
- Length 列をクリックしてソート
- ほとんどのレスポンスの Length は同じ
- 1 つだけ Length が違うエントリ がある
そのレスポンスを確認すると
- 他のエントリ:
Invalid username - このエントリ:
Incorrect password
- 他のエントリ:
- → このレスポンスの Payload(ユーザ名)が “実在ユーザ”
なぜこれでわかる? → アプリが
- ユーザが存在しない場合 → Invalid username
- ユーザは存在するがパスワードが違う場合 → Incorrect password という 異なる応答 を返してしまっているからです。 これが脆弱性そのものです。
ステップ 4 — Intruder を再設定して “パスワード総当たりフェーズ” へ
- Intruder → Positions に戻る
- Clear § を押してすべて削除
- username をさきほど特定した「有効ユーザ名」に固定
- password の値を
§xxx§で囲んでペイロード位置にする
username=valid-user&password=§invalid-password§
- Payloads に candidate passwords を貼り付ける
- Start attack
なぜ? → 今度は「パスワードだけ変える」必要があるため、username は固定し password を Sniper の対象にします。
ステップ 5 — Status 列から 正しいパスワード を特定
Attack のウィンドウで結果を確認。
- Status 列 を見比べる
- 大半は 200 OK(ログイン失敗)
- 1 つだけ 302(リダイレクト)など挙動が異なるものがある
- このエントリの Payload に表示されている password が 正解
なぜ 302 なのか? → ログイン成功した場合、アプリは「アカウントページ」へリダイレクトするため Status が変化するためです。
ステップ 6 — 正しい認証情報でログインしてラボクリア
得られた
- 正しいユーザ名
- 正しいパスワード をログインフォームに入力
- My account ページに到達
- ラボが Solved 状態になる
よくある失敗と対処法
| 症状 | 原因・対処 |
|---|---|
| Length が全部同じ | 本文の差異(メッセージ内容)を比較する。HTMLコメントや位置の微妙な違いがヒントの場合もある。 |
| 302 が出ない | Cookie が切れている/セッションが必要。Intruder の request headers を確認。 |
| エラーが全部同じ | 正しい Payload list を貼っていない可能性。ラボが提供する Candidate usernames / passwords を使う。 |
| Intruder が遅い | Burp の resource pool 制限。低速になるが結果には影響なし。 |
セキュリティ的な学び(なぜ危険か)
- エラーメッセージの差異は情報漏洩の原因となる
- 正しいユーザ名さえ分かればパスワード総当たりが容易になる
- 認証周りは常に “同じエラーメッセージ・同じレスポンス時間” が必須
実務では次の対策が必須:
- ユーザ名とパスワードどちらが間違っていても同じエラーを返す
- レート制限(Rate Limit)・アカウントロック・CAPTCHA の導入
- ログイン試行を監視・警告
まとめ(ワンフレーズ)
レスポンスの違いから実在ユーザを特定し、そのユーザに対してパスワード総当たりを行い、正しい組み合わせでログインしてラボをクリアする。
Best regards, (^^ゞ