Protocol Buffers用のBurp Suite拡張機能

# はじめに
Protocol Buffers (以下、Protobuf) を使った通信の脆弱性診断って大変ですよね。  
なので Burp Suite (以下、Burp) で診断を行う際に Json で送信すると Protobuf メッセージに変更する拡張機能を作成しました。  

Protobuf を扱うための拡張機能は他にもありますが、よければ使ってみてください！

# 作成した拡張機能

こちらです。
- [protobufHandler](https://github.com/WhaleMountain/protobufHandler) 

[リリース](https://github.com/WhaleMountain/protobufHandler/releases) から jar ファイルをダウンロードして、Burp の Extensions からインストールしてください。

## 機能

- [Handler](#handler-の使い方)
    - Burp の Proxy、Repeater、Intruder、Scanner、Extensions を通過するリクエスト、レスポンスに対して、Json から Protobuf メッセージへの変換を行います
- [Editor](#editor-の使い方)
    - Burp のメッセージエディターに Protobuf メッセージを Json フォーマットに変換するタブを表示します
    - エディター上の Json を変更して送信すると、 Protobuf メッセージに変換され送信されます

## 動作確認環境

* macOS Sonoma
* Burp Suite Professional v2024.9.5
* OpenJDK 21.0.5

## 事前準備

1. [Protocol Buffer Compiler Installation](https://grpc.io/docs/protoc-installation/) を参考に適宜 `protoc` コマンドをインストールしてください。 
1. 拡張機能で読み込むための Descriptor ファイルを作成します

```sh
$ cd protobufHandler/example/proto
$ protoc --descriptor_set_out=./hello.desc *.proto
$ ls
hello.desc  hello.proto user.proto
#  ↑これを作成する
```
:::note warn
拡張子は必ず `.desc` としてください。
:::

import ファイルが複数ある場合などは適宜 `--proto_path` オプションなどを追加してください。
```sh
#例
protoc --proto_path=./protobuf/:. --descriptor_set_out=./hello.desc *.proto
```

## Handler の使い方

リクエスト、レスポンスをハンドリングし、Protobuf メッセージに変換する手順を記載します。

### Request handling

リクエストボディを Json の状態で送信したときに、Protobuf メッセージに変換する手順を説明します。

1. 対象のリクエストを Burp の Target Scope に登録します
1. 対象のリクエストの Body に Json を記述します
![request-handler-json.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1994500/078c87e2-7c5e-e5a7-961f-7c7d10667c7f.png)
1. Protobuf Handler のタブを開き、「New」ボタンで新しいルールを追加します
1. 画面に表示されている項目を入力します
    - Scope: 対象となるリクエストを指定 (正規表現は**不可**)
    - Protobuf File: descriptor_set_out で出力したファイルを選択
    - Message Type: Protobuf に変換する定義を指定
    - Tool Scope: どのツールから送信されたリクエストを対象とするか指定
    - Handling Scope: Request を選択
    - Comment: 任意。その時の気持ちなど (コメントセルをダブルクリックで編集できます)
1. 入力後、「Save」ボタンをクリックして保存します
1. テーブルの「Enable」にチェックを入れ準備は完了です
![request-handler-rule.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1994500/e15cb14c-aab1-9d9e-02c1-c4719b42dbd4.png)
1. Repeater タブに戻り、2で用意したリクエストを送信します
![request-handler-send.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1994500/17b8bfc3-c9aa-17cb-35e4-9d6f6c129458.png)
1. Logger を表示すると、Protobuf に変換されていることを確認できます
![request-handler-log.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1994500/0f6355be-390b-e3ed-7861-ed8c149878f3.png)

:::note info
補足
ActiveScan++ など拡張機能から送信される Scan リクエストは「Extensions」で送信されます。そのため Scan で使用する場合は、Tool Scope に 「Scan」「Extensions」の2つにチェックを入れることをおすすめします。
:::

### Response handling

レスポンスボディを Protobuf メッセージに変換することができます。またオプションでボディを Json に置換し、 Protobuf メッセージに変換することも可能です。

1. レスポンスを書き換える対象のリクエストを Burp の Target Scope に登録します
1. 予め書き換え対象のリクエストの通常時のレスポンスを確認します
![response-handler-raw.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1994500/8574a49b-7f40-8be1-9e46-521bc898c4c1.png)
1. Protobuf Handler のタブを開き、「New」ボタンで新しいルールを追加します
1. 画面に表示される項目を入力します
    - Scope: 対象となるリクエストを指定 (このリクエストのレスポンスを書き換える)
    - Protobuf File: descriptor_set_out で出力したファイルを選択
    - Messsage Type: Protobuf に変換する定義を指定
    - Tool Scope: どのツールのレスポンスを対象とするか指定
    - Handling Scope: Response を選択
    - (Optional) Replaced Response Body: ボディの中身を固定にする場合に指定
    - Comment: 任意。気分 (コメントセルをダブルクリックで編集できます)
1. 入力後、「Save」ボタンをクリックして保存します
1. テーブルの「Enable」にチェックを入れ準備は完了です
![response-handler-rule.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1994500/7e325277-26fa-6e7d-8713-bf51de681e90.png)
1. Repeater タブに戻り、リクエストを送信します
1. レスポンスの中身が書き換わっていることを確認できます
![response-handler-send.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1994500/03c977c1-24bb-3d60-9ed3-ef7a5d4f32a7.png)
1. また Logger でも書き換わっていることを確認できます
![response-handler-log.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1994500/4d45634e-b876-e274-8f4e-25784c2eadf9.png)

## Editor の使い方

Repeater で Protobuf メッセージを Json に変換する方法、変換後の Json を編集して Protobuf メッセージで送信する手順を記載します。

1. Repeater タブに対象のリクエストを送信する
1. サポートしている `Content-Type` の時、「Protobuf to Json Decode」タブが表示されます
1. Protobuf to Json Decode タブを選択すると Raw フォーマットで表示されます
![editor-raw.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1994500/8258c61f-5314-bd16-e848-6510c6559274.png)
1. 「Choose」ボタンで descriptor_set_out で出力したファイルを選択します
1. 読み込みに成功すると Message Type が選択できるようになります
![editor-message.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1994500/54bd4c8a-1de5-71dd-fccf-2df5ac89303d.png)
1. デコードしたい Message Type を選択し、「Decode」ボタンをクリックしてください
![editor-decode.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1994500/bdc98d1d-26ed-688f-92f2-de4d8eacc80e.png)
1. 出力された Json を編集し「Send」をクリックする
![editor-send.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1994500/34b175a9-4eb4-0ae1-7d76-80d32b46370b.png)
1. Logger を表示すると、Protobuf に変換されていることを確認できます
![editor-log.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1994500/f3092311-9c19-0504-0958-219d4988579d.png)


::: note info
サポートしている Content-Type
application/x-protobuf
application/protobuf
application/grpc-web+proto
:::

# 補足

色々テストできていない部分ありますので、使用は自己責任でお願いします。  
不具合あればコメントなどで教えていただけると助かります！

# 参考記事

- [montoya-api](https://portswigger.github.io/burp-extensions-montoya-api/javadoc/burp/api/montoya/MontoyaApi.html)
- [Protocol Buffers
](https://protobuf.dev/)
- [protobuf-java 3.25.1](https://javadoc.io/doc/com.google.protobuf/protobuf-java/3.25.1/overview-summary.html)