Shikata Ga Nai

Private? There is no such things.

【有料試作版】PortSwigger LAB攻略:Multi-step process with no access control on one step

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をプロキシにしている場合、連続して以下のようなリクエストが見えるはず:

    1. 昇格リクエスト(POSTやGETで /admin-roles など)
    2. 確認リクエスト(“Confirm”ボタンで再度別エンドポイントに飛ぶ、または同エンドポイントだが別パラメータ)
  • なぜ? どのリクエストが決定打(実際にロールが変わる)になっているかを見極めるため。たいていは「確認」タイミングのリクエストが決定打。

典型的な通信例(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)
  • 必須パラメータusernameaction=upgrade
  • CSRFトークンの有無(多くのLABでは「このステップだけCSRF/認可が無い」ことがある)
  • Cookiesession= の値)

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のProxywienerとして何か1リクエストを通す→HTTP historyからCookie: session=...を確認してコピー
  • なぜ? 後で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=carlosusername=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-Typeaction パラメータの綴り。
  • 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表示。

実運用での対策(開発者向けチェックリスト)

  1. ステップごとに認可

    • 「管理者であること」を全エンドポイントで検証。
  2. サーバ側でのロール確認

    • クライアント送信の roleaction を鵜呑みにしない。
  3. 最終決定APIに特に厳格なチェック

    • 確認・完了ステップにCSRF対策+認可を重ねる。
  4. ID/対象のサーバ側再解決

    • username=wiener を受け取ってもサーバ側で本人性・権限を再評価
  5. テストケースの強化

    • 非管理者のCookieで全ステップを再送」という負のテストを自動化。

まとめ(今回の操作の最小手順おさらい)

  1. 管理者 administrator:admin でログイン → Adminパネルで carlos を昇格 → 確認リクエストをBurp Repeaterへ。
  2. 別のシークレットウィンドウで wiener:peter でログイン → wienerのsession Cookieを取得。
  3. Repeaterの確認リクエストで

    • Cookie: session=...wienerの値に差し替え、
    • username=wiener に書き換えて送信。
  4. wieneradministrator になっていればLABクリア。

Best regards, (^^ゞ