HTTP Request と Response の改ざんを Burp Suite Community Edition で試す
ゴール
Burp Suite の proxy 機能を使って、Webアプリケーションへのリクエストとレスポンスをインターセプトして、リクエストとレスポンスのそれぞれをいじる手順を理解する
教材
公式のTutorialを使う。 Burp Suite は無償 の Community Edtion を使う
インストール と 起動
M1 Mac で試すので Homebrew cask で インストールすることにした
brew install burp-suite
バージョンは Community 2024.9.5
起動
- 起動すると同意画面になるので agree
- project の保存先を選ぶ
- Community Edition は Disk-based projects をサポートしていないので、Temporary project in memory
- 設定ファイルの読み込み
- 今回は Use Burp defaults
- カスタムファイルを作って読み込むこともできる
以上で起動した。
ちなみにキャプチャは、 Settings > User interface > Display で、Appearance を Dark にした後のもの
Burp Proxy で HTTP 通信をインターセプトしてみる
この内容を試す
Proxy の Intercept を On にする
Proxy > Intercept タブ で Intercept on
にする。 Intercept off
がトリガーボタンになってて、ここをクリックすることで on/off が切り替わる
Intercept off 状態
Intercept on 状態
ブラウザ を起動する
Open browser
を押すと Burp用のブラウザ が起動する。 Chromium ベースのブラウザでこれでリクエストすると内部で Burp を proxy にするように設定されていてHTTPトラフィックをインターセプトしてくれているんだと思う
リクエストをインターセプトする
Burp用ブラウザを起動したときにデフォルトURLが動くので、Burp側で Drop
を押してクリアした後、チュートリアルにある https://portswigger.net
をブラウザからアクセスしてみると、リクエストがキャプチャされた
リクエストを送信する
前段でブラウザからURLにリクエストした段階では、またBurpがインターセプトした状態で止まっていてWebサーバーにリクエストが送信されていない。
送信する場合は、送信したいリクエストを選択した状態で Burp の Forward
ボタンを押す。 するとWebサーバにリクエストしてレスポンスが返ってくる。
なお、この時点ではBurpで レスポンスを見る方法が不明
インターセプトをoff にしてProxyを無効にする
ここまでの状態で、Burp で Intercept off
にした後、Burp用ブラウザから同じリクエストを送信すると今度は Burp がインターセプトしなくなり、forwardしなくてもレスポンスがブラウザに返ってくる
HTTP history から HTTPトラフィックを確認する
HTTP history タブに切り替えると ここまでで Burp Proxy を通った HTTP通信が一覧で表示される。特定のリクエストを選択すると、その通信の リクエストとレスポンスが確認できる
Chrome などのブラウザのリクエストを Burp で インターセプトする
Burp用ブラウザではなく、ローカル端末にインストールしている Chrome, Firefox, Safari を使って Burp で インターセプトしたい場合はリンク先の通りの設定が必要
- Burp の proxy listener を 有効にして 端末に対する Proxy として利用できるように設定する
- Chromeをはじめブラウザの各種設定でProxyとして前述の Burpを proxy として設定する
- BurpのCA証明書をインストールして、HTTPS通信もBurpでインターセプトして通信内容を正常に読み取れるようにする。
- (これを行わないと、ブラウザ側がBurp proxy を信頼できないWebサーバーとして認識するので本番と同等の状況にならないため)
Burp用ブラウザ は これらの設定をプリセットしたような状態なので、特に支障がなければ このブラウザを使うことが推奨されているっぽい
Burpブラウザを利用した場合、intercept off でも proxy として リクエスト・レスポンスはキャプチャしているのがわかった。
これによって後述する replace なんかは intercept しなくても実行することができる。
Burpの intercept って リクエストあるいはレスポンスの通信を停めて 内容を確認したり書き換えて本来のリクエスト先に送信する機能だと認識した
インターセプトしたHTTPリクエストを改ざんしてみる
このセクションの話
前提として、テストサイトを利用するために ここから アカウント登録を行う
テストサイト まで進める
まずは テスト対象ページまで進める
- Burp の Intercept を Off にする
- Burpブラウザから
https://portswigger.net/web-security/logic-flaws/examples/lab-logic-flaws-excessive-trust-in-client-side-controls
にリクエストする -
ACCESS THE LAB
をクリックしてログイン画面を表示する - 事前に登録した自分のアカウントでログインする
- ログインできると テストサイトである ECサイトが表示される
テストサイトにログインして商品を選択する
チュートリアルは、商品をカートに入れるPostリクエストをインターセプトするのでそこまでの操作を進める
-
My account
を選択し、 Username: wiener, Password: peter でログインする
- Credit として $100.00 持っている
- Emailの更新は不要
-
Home
リンクをクリックしてトップページに戻り、Lightweight "l33t" Leather Jacket
の詳細をクリックし、商品の詳細画面を表示する
- ここで一旦、Add Cart を押し、画面が更新されたら 右上の Cartアイコンをクリックしてみる
- Price欄が、$1337.00 と正規の金額となっていることを確認する
- Removeをクリックしてカートをクリアし、また同じ商品の詳細画面に戻る
- こうするとこの後の操作がわかりやすいと思う
- Burp で インターセプトをOnにする
- 商品ページに戻って、商品数は 1 のまま
Add to cart
を押す - POSTリクエスト
POST /cart
が Burp でキャプチャされる。リクエストを見た時に パラメータがセットされているのを確認する
リクエストを改ざんしてみる
- Burpのリクエスト情報から 直接編集ができるので、
price
を 133700 から 1に変更する
- これは 1セント($0.01)を意味する
- 該当Postリクエストを選択して、Forward から
Forward All
をクリックしてサーバーに送信する - Burpブラウザがリロードされることを確認する
- ちょっとわかりづらいが、タブに更新アイコンが表示されるのでそこで確認する
- レスポンスは同じ商品詳細画面になるので、更新されたかわかりづらい
- 更新が終わったら インターセプトをOff にする
- Cartアイコンをクリックして、カートの内容をみると 商品の Priceが $0.01 と改ざんした結果で登録さrていることが確認できる
検査対象リクエストを限定する Scope設定
Webサイトは通常 外部サイトへのアクセスなどもありその全てをBurpでインターセプトするのは無駄な時がある。このような場合に 対象リクエストをスコープに指定すればフィルタリングが行える
- Burp で Proxy > HTTP history タブに切り替える
- これは必須ではなくて、historyを見ることでどのようなサイトへのリクエストをインターセプトしたかを確認するための模様
- Target > Site map タブに切り替える。
- 右側のホストのリストから 対象にするサイトで右クリック > Add to scope を選択する
- Proxy > HTTP history タブに戻り、Filter settings をクリックして、HTTP history filter 画面を表示する
- Filter by request type > Show only in-scope items を チェックして、Apply & close すると history に scope に指定したtargetのみ表示するようにフィルタリングされる
Burp Repeater で リクエストを再送する
- Proxy -> HTTP history タブを開き、
GET /product
リクエストを探す - リクエストURLを右クリックして、
Send to Repeater
を選ぶ - Repeter タブに移動する
- 追加したURLが表示されているので
Send
をクリックする- この時は、InterceptはOffでもキャプチャしてくれる
- しばらくすると、Responseが返ってくる
- この Repeter の リクエストはパラメータを変更して送信することができるのとその結果は履歴として追える
この時は、InterceptはOffでもキャプチャしてくれる
Repeter で リクエストを送信したときは Burpブラウザの表示は更新されなかったので、Burpブラウザ経由ではリクエストをインターセプトしていなくて、Burpだけでリクエスト送信していると考えられる
これ以降のチュートリアルは Professional版向けなのでスキップする
Webサーバーからのレスポンスを改ざんする
ここまで Webサーバーに対するリクエストを改ざんする方法だったが、WebサーバーからのレスポンスをBurpでインターセプトして改ざんしてみる
いくつか方法があるみたい
Burpブラウザのレスポンスを改ざんしてみる
- インターセプトON にする
- リクエストをインターセプトする
- インターセプトしたリクエストを右クリックし、 Do intercept -> Response to this request をクリックする
- リクエストをForwardする
- するとWebサーバーからのレスポンスをインターセプトし、レスポンスがキャプチャできる
- レスポンスを編集して、Forwardをする
- 編集したレスポンス内容がBurpブラウザに反映される
ちなみに HTTP history で確認すると、一覧に Edited では出るが、レスポンスは改ざん後ではなく Webサーバーからのレスポンスが出力されていた
HTTP リクエスト/レスポンスの特定の情報をリプレースする
手動更新以外にも リクエストとレスポンスが特定の条件にマッチする場合にデータを置換することもできる
- Burp の Proxy > Match and replace を選択する
- Only apply to in-scope items を選択して、ScopeのURLのみをリプレース対象とする
- Add やEdit などを利用して HTTP リクエスト/レスポンス の各種アイテムに対して、条件に一致した場合に置換する情報を設定する
- Enabled にした条件が リクエスト・レスポンスで適用される
設定例
実務で使うケースを元にした設定例をいくつか。
設定画面で Original request/response の 横にある Test
をクリックすると想定結果が確認できる
レスポンスに JSスクリプトを埋め込む
<head>タグの最後に埋め込む例
- Type: Response body
- Match: </head>
- Replace: <script src="{埋め込むJS}"></script></head>
リクエストヘッダを埋め込む
任意のリクエストヘッダを埋め込む
- Type: Request header
- Match: なし (指定しない場合は常に追加される)
- Replace: 埋め込みたいヘッダ情報
レスポンスヘッダを埋め込む
CSPのディレクティブを上書きする
- Type: Response header
- Match: script-src
- Replace: script-src {埋め込むデータ}
動作確認の時に Original response の レスポンスヘッダに CSPを追加しておくと確認できる
追加したものを こんな感じで 有効にしておく
で、Scope対象のリクエストをBurpブラウザで実行すると置換された
HTTP history だと、Edited request や Auto-modified response で表示すると埋め込まれたことが確認できる
Burpブラウザのソース上でも埋め込まれているのを確認できた
Burpブラウザを利用している場合は、intercept off でもreplaceが実行されるのを確認した。他のブラウザでも同じかは未確認