CSRFトークン・バイパス

WEBの脆弱性診断で、ログインフォームに対してブルートフォースアタックを試みる際に、いくつかパターンがある。

  1. ログインIDとパスワードのみの認証
  2. ログインIDとパスワードとCSRFトークンによる認証
  3. ログインIDとパスワードとCSRFトークンとcookieのセッションによる認証
  4. さらにその他

RailsやLaravelなどのフレームワークを使って基本的なログインフォームを作っている場合は、3番が多いと思う。ちなみに、CSRFトークンとcookieのセッションは毎度変わるので、ひたすらPOST連打というわけにはいかない。

では、1番3番(2番も考え方は一緒)を例にして、CSRFトークンとcookieのセッションをどうやってパイパスして、ブルートフォースをするかを「Burp Suite」で検証してみる。

1番の場合(簡単)

認証が、ログインIDとパスワードだけの場合、ブルートフォースはシンプルだ。

上記の様に、ひたすら赤矢印をPOSTして検証することができるので簡単だ。そもそも、最初の「GET」すら要らないで成立する。

しかしWEBサービスが、CSRF対策をしている場合は、上記のように簡単にはいかない。

2番、3番の場合(CSRF対策がなされている)

この場合、先程のようにPOST連打というわけにはいかない。

この様に、いきなりPOST連打だと、CSRFトークン(毎度変わる)がセットされていないため、ブルートフォースは成立しない。すなわち、POSTする度にまず先にGETをして、cookeiとcsrfTokenを取得して、それを使ってPOSTする必要があるわけだ。図にすると以下のようになる。

POSTの前に、上記の青矢印を実行する必要が有る。以下の手順で、ひたすら繰返して上げる必要が有る。

  1. GETして、WEBサーバーから毎回変わる、cookie(session)と、csrfTokenを取得
  2. POSTの際に、cookie(session)と、csrfTokenをセットしてブルートフォースを実行

上記の手順を、Burp Suiteで自動化してみる。

これが今回のテーマである、「CSRFバイパス」だ。

Burp Suiteの自動化手順

結論として、POSTによるブルートフォースは、通常通り「Intruder」を使用して、GETの部分はマクロで定義してPOST前に組み込んであげる。

Intruderの設定

  • ブラウザのProxy設定でBurp Suiteを指定する。
  • ブラウザから対象のWEBサーバーのログイン画面を開く。
  • Burp SuiteのProxyで、Interseptを「ON」にする。
  • ブラウザから、ログインフォームに対して適当な値を入れてみる。以下の例だと、username=test、password=test。
  • Burp SuiteによりブラウザのリクエストがInterseptされて、詳細を見ることができる。

上記のような感じでPOSTする際に、「username」と「passowrd」だけでなく、「cookie(session)」と「csrfToken(上記では、loginToken)」もサーバーに送信されていることが解る。

この、「cookie(session)」と「loginToken」はリクエストの度に変わるので、毎度取得してPOSTの際にセットしてあげる必要が有る。

  • Interceptしたリクエストを、「Intruder」に送る。
  • Intruderで、辞書ファイルの設定する。

Intruderを開くと自動で、「cookie(session)」と「loginToken」と「username」と「password」の全てが、辞書ファイルの挿入対象になってしまっている。

今回は、「username」と「password」は、Intruder(辞書ファイル)からセット、「cookie(session)」と「loginToken」はマクロにより、GETした内容をセットにしたいので、

  1. 1度「Crear」をクリックして全部対象から外す。
  2. usernameのバリュー(上記の場合test)と、passwordのバリュー(上記の場合test)を選択して、手動で「Add」する。

マクロの作成

  • 「Settings」をクリック
  • Settingsの別ウィンドウが開くので、「Project」「Sessions」を選択
  • 「Macros」の「Add」をクリック。
  • リクエストの履歴が表示されるので、マクロに使用したいリクエストを選択。

今回の場合は、POST前のGETをマクロに使用したいので、それを探して選択する。

以下の画面になるので、適当に名前を付けて「OK」ボタンを押してマクロを保存する。

作成したマクロを実行したいリクエストに紐付ける

  • 上記までの操作をすると、カレントのコンテキストは、「Settings」の「Project」の「Sessions」に戻るはずなので、そのまま上の方の「Session handling rules」までスクロールする。
  • 「Add」を押す。

そうすると、「Session handling rule editor」のウィンドウが開く。「Details」と「Scope」の2つのタブがあり、「Scope」を開く。

  • 「Tools scope」のチェックボックスを今回使用する、「Intruder」のみにする。
  • 「Include in scope」で、今回対象のUILを「Use custom scope」で「Add」する。
  • 「OK」ボタンを押す。

次に、「Details」をクリックする。

  • 「Rule description」に解りやすいルール名を付ける
  • 「Rule actions」で、「Add」を押して、「Run a macro」をクリック

そうるすと、以下の画面となる。

この画面は、

「このアクションは定義済みのマクロを実行し、現在のリクエストのパラメータ、ヘッダー、クッキーを更新します。」

と、言っている。まさに定義済み(GETマクロ)を実行し、その結果で(cookie(session)、loginToken)このリクエストを上書きしてほしいのだ。

  • 「Select macro」で、先程作成したマクロを選択する。
  • 「Update only the following parameters and headers:」にチェックを入れ、上記指定のマクロ(GET)で取得できる「loginToken」を指定する。
  • 「Update only the following cookies:」にチェックを入れ、上記指定のマクロ(GET)で取得できる「session」を指定する。
  • 「OK」ボタンを押す。

さて、ここまで来たら、最初に定義したこの図を達成したことになる。

Intruderの実行

「Start attack」を押して、Intruder(ブルートフォース)を実行する。

これにて、POST連発のブルートフォースではなく、

  1. GETして、WEBサーバーから毎回変わる、cookie(session)と、csrfTokenを取得
  2. POSTの際に、cookie(session)と、csrfTokenをセットしてブルートフォースを実行

を、指定した辞書ファイルのワード数分、繰返しブルートフォースできる。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です