Hello there, ('ω')ノ
このLABは「管理者パネルの多段階フローのうち、ある1ステップだけ認可チェックが抜けている」という典型的なアクセス制御不備を突きます。
ゴールは、一般ユーザー wiener:peter でログインした状態から、自分のロールをadministratorへ昇格させること。
全体像(最初に戦略を立てる)
- 多段階フロー=「(1) 昇格リクエスト」→「(2) 確認操作」→「(3) 完了」という流れを想定。
- 想定される失敗=(2) 確認操作のエンドポイントだけ、「誰が叩いても通ってしまう」状態。
- したがって、管理者で一度フローを踏み、確認用リクエストの“形”をBurpで保存。
- その同じリクエストを、一般ユーザーのセッションCookieに差し替えて送信すれば、認可抜けを突けるはず。
思考のポイント: 多段階フローは「1画面1チェック」になりがち。開発者が“途中のAPI”で認可を省略するパターンは本当によくあります。
ステップ1:管理者で実際のフローを踏んで、リクエストを観察する
1-1. 管理者でログイン
- ブラウザでLABを開き、
administrator:adminでログイン。 - なぜ? 管理者専用フローを正しい手順で一度踏むことで、どのエンドポイントが呼ばれるかを観測するため。
1-2. Adminパネルへ移動し、昇格操作を開始
- 画面上部に
Admin panelなどのリンクがあるので遷移。 - ユーザー一覧から
carlosを管理者へ昇格する(Promote, Make adminなどのボタン)。 - なぜ? 任意ユーザー昇格フローの通信(HTTPリクエストの形)をBurpでキャプチャしたいから。標的は誰でもよく、まずは正規操作として1回成功させる。
1-3. BurpでHTTPを確認(Proxy/HTTP history)
Burpをプロキシにしている場合、連続して以下のようなリクエストが見えるはず:
- 昇格リクエスト(POSTやGETで
/admin-rolesなど) - 確認リクエスト(“Confirm”ボタンで再度別エンドポイントに飛ぶ、または同エンドポイントだが別パラメータ)
- 昇格リクエスト(POSTやGETで
- なぜ? どのリクエストが決定打(実際にロールが変わる)になっているかを見極めるため。たいていは「確認」タイミングのリクエストが決定打。
典型的な通信例(LABにより細部は異なりますが、概念は共通)
POST /admin-roles HTTP/1.1 Host: YOUR-LAB-ID.web-security-academy.net Cookie: session=ADMIN_SESSION_XXXX Content-Type: application/x-www-form-urlencoded username=carlos&action=upgrade
その後に「本当に昇格しますか?」の画面が出て、確認を押すと:
POST /admin-roles/confirm HTTP/1.1 Host: YOUR-LAB-ID.web-security-academy.net Cookie: session=ADMIN_SESSION_XXXX Content-Type: application/x-www-form-urlencoded username=carlos&action=upgrade
観察ポイント:
- エンドポイントURL(例:
/admin-roles/confirm)- HTTPメソッド(POST/GET)
- 必須パラメータ(
usernameやaction=upgrade)- CSRFトークンの有無(多くのLABでは「このステップだけCSRF/認可が無い」ことがある)
- Cookie(
session=の値)
1-4. 確認リクエストをRepeaterへ送る
- BurpのHTTP historyで確認リクエストを右クリック → "Send to Repeater"。
- なぜ? このリクエストこそが脆弱なステップの可能性大。あとでCookieだけ入れ替えて再送するアタックの土台になる。
ステップ2:一般ユーザーのセッションを準備する(別ウィンドウで)
2-1. シークレットウィンドウ(プライベート/インコグニート)を開く
- 別セッション環境を作るために必ず新しいプライベートウィンドウでLABを開く。
wiener:peterでログイン。- なぜ? 管理者とセッションCookieが混ざらないようにするため。現実の攻撃でも別の被害者になりきる発想は重要。
2-2. 一般ユーザーのCookieを取得
取得方法は2通り:
- (A) ブラウザの開発者ツール → Application/Storage → Cookies →
sessionの値をコピー - (B) BurpのProxyで
wienerとして何か1リクエストを通す→HTTP historyからCookie: session=...を確認してコピー
- (A) ブラウザの開発者ツール → Application/Storage → Cookies →
- なぜ? 後でRepeaterでCookie差し替えを行い、同じ確認リクエストを一般ユーザーの権限で叩き直すため。
ステップ3:RepeaterでCookieを差し替え、ターゲットを自分に変更して送る
3-1. Repeaterの保存済み「確認リクエスト」を開く
- 先ほど送った
/admin-roles/confirm(名称はLABにより異なる)を開く。
3-2. Cookieを一般ユーザーのセッションへ置換
- ヘッダ部の
Cookie: session=ADMIN_SESSION_XXXX
を
Cookie: session=WIENER_SESSION_YYYY
に差し替える。
- なぜ? 管理者でなくても通るかを検証したい。これが通るなら認可チェック欠落が確定。
3-3. username を自分(wiener)に変更
- ボディやクエリにある
username=carlosをusername=wienerに変更。 - なぜ? 自分自身のロールを昇格させて、ゴール(wienerをadminに)を達成するため。
送信例
POST /admin-roles/confirm HTTP/1.1 Host: YOUR-LAB-ID.web-security-academy.net Cookie: session=WIENER_SESSION_YYYY Content-Type: application/x-www-form-urlencoded username=wiener&action=upgrade
3-4. 送信してレスポンスを確認
- ステータスコードが200や302(リダイレクト)で、エラーが出ていないか確認。
- 念のためブラウザの
wienerセッションに戻り、ページをリロードすると、管理者権限に変わっている(Admin panelが見える、プロフィールにadmin表記など)。
うまくいかない場合のチェックリスト:
- エンドポイントを確認ステップのものにしているか(最初の“昇格リクエスト”ではない)。
- CSRFトークンが必要なら、確認ステップに無いことを再確認(ある場合は値ごと差し替えが必要)。
Content-Typeやactionパラメータの綴り。- Cookieの貼り替えミス(前後空白や改行、別Cookie混在)。
なぜこれで通るのか(脆弱性の本質)
認可はリクエストごとに必ず行うべきですが、開発現場では
- 「最初の画面で管理者をチェックしたからOK」
- 「確認は同じ人が押す前提」 という思い込みで、途中APIに認可チェックが実装されないことがあります。
- 結果として、確認APIが“誰のセッションでも動く”危険な状態になり、一般ユーザーのCookieで叩くだけで管理操作が成立してしまいます。
さらに深める:観察時に見るべき具体ポイント
- メソッドとエンドポイント:
/admin-roles/confirm、/users/role/confirmなど、“confirm, finalize, complete”といった語がつくことが多い。 - パラメータ:
username/role=administrator/action=upgradeなど。パラメータだけで対象と操作が決まるAPIは要注意。 - CSRFトークン:あるステップにあっても、確認ステップだけ無いケースが狙い目。
- Referer/Origin:ヘッダがなくても受け入れてしまうエンドポイントは脆弱度が高い。
- レスポンス:成否メッセージ、リダイレクト先、変更後のUI表示。
実運用での対策(開発者向けチェックリスト)
ステップごとに認可
- 「管理者であること」を全エンドポイントで検証。
サーバ側でのロール確認
- クライアント送信の
roleやactionを鵜呑みにしない。
- クライアント送信の
最終決定APIに特に厳格なチェック
- 確認・完了ステップにCSRF対策+認可を重ねる。
ID/対象のサーバ側再解決
username=wienerを受け取ってもサーバ側で本人性・権限を再評価。
テストケースの強化
- 「非管理者のCookieで全ステップを再送」という負のテストを自動化。
まとめ(今回の操作の最小手順おさらい)
- 管理者
administrator:adminでログイン → Adminパネルでcarlosを昇格 → 確認リクエストをBurp Repeaterへ。 - 別のシークレットウィンドウで
wiener:peterでログイン → wienerのsessionCookieを取得。 Repeaterの確認リクエストで
Cookie: session=...を wienerの値に差し替え、username=wienerに書き換えて送信。
wienerが administrator になっていればLABクリア。
Best regards, (^^ゞ