Burp拡張機能 作成入門・前編
はじめに
Burp Suiteはセキュリティ診断等に利用されるローカルプロキシツールです。
ローカルプロキシツールとは、ローカルコンピュータ上で動作するプロキシサーバのようなものです。
Webブラウザとサーバ間の通信経路上にローカルプロキシを配置することで、その通信内容を傍受、改ざんが可能になります。
Webアプリケーションの診断ではこのようなローカルプロキシツールを用い、攻撃者の立場で実際に通信を改ざんし、脆弱性の有無を検査しています。
Burpのようなローカルプロキシツールは他にもいくつかありますが、Burpが最も機能豊富で使いやすい、という印象です。
さて、弊診断チームでも大変お世話になっているBurpではありますが、やはり実際の診断業務での利用を想定すると、社内独自のフォーマットに書き出したかったり、他ツールとの連携を考えたくなります。
弊診断チームでも運用でカバーしている点は多々ありますが、やはり業務効率化を考えると、単純作業は自動化したいところです。
ありがたいことに、Burpを提供するPortswigger社はBurp拡張機能を作成するためのAPIを公開しています。
Burp拡張機能とは、文字通りBurp上で動作するJavaプログラムで、APIを利用すれば誰でも作成することが可能です。
そこで、本稿ではBurpは利用しているが、Burp拡張機能作成をしたことのない方向けに、簡単な例を交えて拡張機能の作成方法を前後編で解説したいと思います。
拡張機能作成のための環境構築
Burpの拡張機能はJava、Python、Rubyで作成することが可能ですが、2022年にリニューアルされたBurpのAPIであるMontoya APIは現状Javaだけの対応となっています。
いままでのレガシーなAPIも引き続き利用可能ではありますが、リニューアルされたAPIの方ができることが増えていたり、書き方がモダンになっています。
簡単な拡張機能なら、ハードルが低いPythonで書いてしまいたい気もしますが、今更Python 2.x系を書く気にはならないので、本稿ではMontoya APIを利用するためにJavaを利用して開発を進めていきたいと思います。
まず環境構築についてですが、とりあえずDockerとgradleで最低限ビルドできる構成にして余計なことを考えないようにします。
Dockerのインストール方法はネット上にたくさんあるので、任意のものを参考にしてください。
とりあえず下記構成にしていただければ、Dockerの細かいことは把握していなくても大丈夫です。
というわけで、以下のようなディレクトリ構成を作成します。
Dockerfile、docker-compose.ymlはそれぞれ以下の通りです。
- Dockerfile
- build.gradle
特別難しいことはしないで、gradleがビルドできるコンテナを用意して、その中に入ってビルドコマンドを実行する構成です。
あとはdocker-compose.ymlがあるディレクトリで以下コマンドを実行してビルド用のコンテナを立てておきます。
次にbuild.gradleの中身ですが、公式ページにある通り、implementionを設定して、その他Javaのコンパイルに必要なことだけ記述しておきます。
以上でBurp Extensionに必要な最低限の環境が用意できました。
あとはお好みでDockerfileをいじったり、gradleを拡張してみてください。
拡張機能の基本的な作成方法
というわけでまずはHelloWorldしてみたいと思います。
SampleExtension.javaに以下内容を記述します。
公式ページに書いてある通りなので、特に解説するほどではないのですが、Burp Extensionの開発にはBurpExtensionインタフェースを実装したクラスの中でinitializeメソッドをオーバーライドし、その中に処理を書いていきます。
initializeメソッドの引数にMontoyaApiを渡すことでburpの各機能にアクセスすることができるようになります。
今回はごく単純にBurp extensionのコンソールに”Hello World!”の文字列を表示するだけです。
では実際にビルドしてみましょう。環境構築の段階でコンテナは動作しているはずなので、以下コマンドを実行してコンテナの中に入ります。
コンテナに入れたらbuildを実行します。コマンドは以下の通りです。
一番最初はライブラリのダウンロードに少し時間かかりますが、二回目以降はさほど時間はかからないはずです。
ビルドに成功していればproject/build/libsにproject.jarというファイルが出力されているはずです。このファイルをBurpで読み込みます。BurpのExtensionsタブのinstalledにあるAddボタンからこのファイルを読み込むと以下のようなウィンドウが表示されるはずです。
Hello World!が表示されていることが確認できます。簡単ですね。
リクエストのフック
Hello Worldできることは確認したので、実践的な拡張機能を作成するために、Burpが受け取るリクエストをフックして、拡張機能から参照してみます。
SampleExtension.javaと同じディレクトリにRequestHandler.javaを作成し、以下のようなコードを書きます。
(importはわかりやすさのため冗長に書いています。)
急にいろいろとインポートしていて不安になるかもしれませんが、全部BurpのAPIです。
APIの詳しい解説は公式リファレンスを読むのが一番良いです。というより、それ以外ほとんどネット上に情報がないと思います。
RequestToBeSentActionメソッドの引数で受け取っているhttpRequestToBeSentが実際にフックしたリクエスト情報を格納する変数になります。
今回は簡単のために、リクエストのurlを取得するurlメソッドを呼び出し、コンソールに出力してみます。諸々の処理が終わったら最後にcontinueWithメソッドでリクエストを(burp上での)次のフローに渡してやります。
オーバーライドしているもう一つのメソッドResponseReceivedAction はレスポンスを受け取った際に実行されるメソッドです。
今回は何もしませんが、オーバーライドはしておきましょう。
リクエストをフックするためには、burp.api.montoya.http.handler.HttpHandlerを実装したクラスを用意し、このクラスのインスタンスをメインのクラスからregisterHttpHandlerで登録する必要があります。
以下のようにSampleExtension.javaに一文追加しておきます。
ここまでかけたら先ほど同様コンテナ内で以下コマンドを実行します。
出力されたproject.jarをこれまた先ほど同様にburpに登録して拡張機能を適用します。
さて、動作確認です。Burpに繋いでるブラウザで適当にアクセスしてみましょう。別にサーバは建てていませんが、localhostにアクセスしてみます。
URLがログに出力されていますね。これでリクエストの情報が拡張機能側で見えるようになりました。
今回は簡単のためにurlを出力するだけにしてみましたが、urlメソッドと同様にheadersメソッドやbodyメソッドがあるので、リクエストに関する大抵の情報はこれで参照できるかと思います。
おわりに
今回はBurp拡張機能を作成するための環境構築して、Hello World、簡単なリクエストのフックを試してみました。
環境構築は若干、面倒に感じますが、実際のコーディングはそれほど大変ではない印象です。
今回解説した内容だけでは、実用的な拡張機能を作成するのは難しいですが、次回の投稿ではリクエストの編集と設定の保存、GUIの作成を簡単な例を交えて紹介しようと思いますので、よければご覧いただければと思います。